브라우저의 렌더링 원리

김현중·2025년 3월 13일

연구소

목록 보기
15/34

브라우저가 화면에 나타나는 요소를 렌더링 할 때, 웹킷이나 게코 등과 같은 렌더링 엔진을 사용합니다. 렌더링 엔진이 HTML, CSS, js로 렌더링 할 때 CRP(Critical Rendering Path)라는 프로세스를 사용하며 다음 단계들로 이루어집니다.

1. DOM 트리 구축

브라우저는 HTML을 파싱하여 DOM(Document Object Model) 트리를 생성합니다. 각 HTML 태그는 DOM 트리의 노드가 되며, 문서의 구조를 표현합니다.

🤔DOM이 뭔데?

DOM은 HTML이나 XML 문서의 프로그래밍 인터페이스입니다. 웹 페이지를 구조화된 표현으로 변환하여 프로그래밍 언어(js)가 문서 구조, 스타일, 내용을 조작할 수 있게 해줍니다.

ex) <div><p>안녕</p></div>라는 HTML이 있다면, DOM은 div 노드 아래에 p 노드가 있고, p 노드 아래에 '안녕' 이라는 텍스트 노드가 있는 트리 구조로 표현됩니다. 이런 DOM을 다루기 위해선 getElementById, querySelector, firstElementChild 등과 같은 브라우저가 제공하는 DOM API를 사용하면 됩니다.

DOM 트리 탐색: querySelector 선택자와 성능 관계

querySelector 사용 시, 선택자 복잡성은 DOM 탐색 효율성에 영향을 줍니다. 브라우저는 선택자를 오른쪽에서 왼쪽으로 평가하며, ID 선택자(#id)가 가장 빠르고, 복잡한 중첩 선택자(.class1 .class2)는 더 많은 연산이 필요합니다. 후손 선택자(div p)는 자식 선택자(div > p)보다 더 넓은 범위를 탐색해 일반적으로 더 느립니다. 하지만 현대 브라우저는 이러한 차이가 크게 체감되지 않을 정도로 최적화되어 있습니다.

BOM(Browser Object Model)??

BOM은 브라우저의 창이나 프레임을 프로그래밍적으로 제어할 수 있게 해주는 객체 모델입니다. 이를 통해 브라우저의 새 창을 열거나 다른 문서로 이동하는 등의 기능을 실행시킬 수 있습니다. 전역 객체로 window가 있으며 하위 객체들로 location, navigator, document, screen, history가 포함되어 있습니다.

2. CSSOM 트리 구축

CSS 파일과 스타일 태그를 파싱하여 CSSOM(CSS Object Model) 트리를 구축합니다.

3. 렌더 트리 구성

DOM과 CSSOM을 결합하여 렌더 트리를 만듭니다. 이 과정에서 display: none과 같이 화면에 표시되지 않는 요소는 렌더 트리에 포함되지 않습니다.

4. 레이아웃 계산 (Reflow)

렌더 트리의 각 노드가 화면에서 정확히 어디에 배치될지 계산합니다. 뷰표트 내에서 위치와 크기가 결정됩니다.

5. 페인팅 (Paint)

레이아웃 정보를 기반으로 픽셀을 화면에 그립니다.

6. 합성 (Compositing)

여러 레이어로 나뉜 페인팅 결과물을 하나의 화면으로 합치는 과정입니다. 현대 브라우저는 성능을 위해 페이지의 다양한 부분을 별도 레이어로 처리하고 이를 GPU를 통해 합성합니다. 이 과정은 레이어 간 겹침을 해결하고 최종 화면을 구성합니다.

JavaScript는 DOM과 CSSOM을 변경할 수 있으며, 이로 인해 렌더링 과정이 다시 시작될 수 있습니다. JavaScript는 일반적으로 파서 차단 리소스로 간주되기 때문에, 브라우저는 JavaScript 파일을 만나면 HTML 파싱을 일시 중지하고 JavaScript를 다운로드하여 실행합니다. 이는 페이지 로딩 시간에 직접적인 영향을 미칠 수 있습니다.



♻️Reflow와 Repaint가 실행되는 시점

Reflow

  • DOM 엘리먼트 추가, 제거 또는 변경
  • CSS 스타일 추가, 제거 또는 변경
  • CSS 스타일을 직접 변경하거나, 클래스를 추가함으로써 레이아웃이 변경됨, 엘리먼트의 길이를 변경하면, DOM 트리에 있는 다른 노드에 영향을 줌
  • CSS3 애니메이션과 트랜지션, 애니메이션의 모든 프레임에서 Reflow 발생
  • offsetWidth와 offsetHeight의 사용. offsetWidth와 offsetHeight 속성을 읽으면, 초기 리플로우가 트리거되어 수치가 계산됨
  • 유저 행동. 유저 인터낵션으로 발생하는 hover 효과, 필드에 텍스트 입력, 창 크기 조정, 글꼴 크기 변경, 스타일 시트 또는 글꼴 전환 등을 활성화하여 리플로우를 트리거할 수 있음

Repaint

  • 가시성이 변경되는 순간 (opacity, background-color, visibility, outline)
  • Reflow가 실행된 순간 뒤에서 실행


✋파서 차단 리소스란?

HTML 파서가 문서를 파싱하는 과정을 일시적으로 중단시키는 리소스를 말합니다. 이로 인해 브라우저의 렌더링이 지연될 수 있습니다.

특징:

  • 주로 동기적으로 로드되는 js 파일이 해당됨
  • <script> 태그를 만나면 브라우저는 스크립트를 다운로드하고 실행할 때까지 HTML 파일을 중단함
  • CSS도 간접적으로 파서를 차단할 수 있음 (js가 CSSOM에 의존해서)

해결 방법:

  • async 속성: 스크립트를 비동기적으로 다운로드하고 준비되면 HTML 파싱을 중단하고 실행 ( <script async src="script.js"></script> )

  • defer 속성: 스크립트를 비동기적으로 다운로드하지만 HTML 파싱이 완료되면 실행 ( <script defer src="script.js"></script> )

  • js 파일을 <body> 태그 끝 부분에 배치하여 HTML이 먼저 파싱되도록 함


🤔그러면 js 파일을 <body> 태그 끝 부분에 배치하는 방식은 리액트같은 SPA에 기본적으로 적용되어있는가?

= 리액트와 같은 SPA 프레임워크들은 일반적으로 빌드 과정에서 최종 HTML에 js 파일을 자동으로 배치함

  1. 기본 배치

대부분의 SPA 빌드 도구는 기본적으로 번들된 js 파일을 </body> 태그 바로 앞에 배치함. 이는 HTML 콘텐츠가 먼저 파싱되도록 하는 권장 방식을 따름

  1. 자동 최적화

최신 빌드 도구들은 js 파일에 자동으로 defer 속성을 추가하거나 적절한 위치에 스크립트를 배치하는 최적화를 수행함

  1. SPA의 특수성

그러나 리액트와 같은 SPA는 초기 HTML이 매우 간단하고, 실제 콘텐츠는 js가 실행된 후에 렌더링 됨. 따라서 스크립트의 위치가 MPA만큼 중요하지 않을 수 있음

  1. 코드 스플리팅

현대적인 SPA는 코드 스플리팅을 통해 필요한 js만 로드하도록 최적화되어 있어, 전체 애플리케이션 코드를 한 번에 로드하는 부담을 줄임


SPA 프레임워크와 같은 빌드 도구는 일반적으로 js 파일을 body 끝에 배치하는 모범 사례를 따르지만, SPA 렌더링 특성상 초기 HTML 파싱이 빠르게 완료되고 실제 콘텐츠 표시는 js 실행에 의존합니다. 이로 인해 더 중요한 것은 js 최적화(코드 스플리팅, 트리 쉐이킹 등)와 효율적인 렌더링 방식(SSR, SSG, ISR 등)의 도입이 됩니다.

SPA와 MPA

  • SPA: 하나의 HTML 파일을 기반으로 js를 이용해 동적으로 화면의 컨텐츠를 바꾸는 방식
  • MAP: 사용자가 페이지를 요청할 때마다, 웹 서버가 요청한 UI와 필요한 데이터를 HTML로 파싱해서 보여주는 방식
profile
박수 받는 사람이 되고 싶어서 항상 노력합니다.

0개의 댓글