Post

브라우저 렌더링 과정

브라우저 렌더링 과정에 대해 정리한 페이지입니다.

브라우저 렌더링 과정

Tags
Rendering

개요

브라우저 렌더링 과정에 대해 정리한 페이지입니다.

브라우저 렌더링 과정

브라우저 렌더링(Browser Rendring)은 HTML, CSS, JavaScript 등의 웹 페이지 자원을 화면에 그리는 과정을 말합니다. 그리고 브라우저 렌더링 과정(Browser Rendering Process)은 웹 페이지를 사용자에게 보여주기 위해 거치는 일련의 과정으로 여러 단계로 구성됩니다. 브라우저 렌더링 과정은 네트워크 요청 → HTML/CSS 파싱 → DOM/CSSOM 생성 → 렌더 트리 생성 → 레이아웃 계산 → 페인팅 → 합성의 순서로 진행됩니다. 브라우저 렌더링 과정을 단계별로 설명하자면 다음과 같습니다.

Step 1 - 네트워크 요청 및 리소스 로드

먼저 사용자가 주소창에 URL을 입력하면 브라우저는 URL을 scheme, hostname, port, path, query, fragment로 분해하여, 해당 URL이 올바른 형식인지 검증합니다.

올바른 형식인 경우 브라우저는 URL을 IP 주소로 변환해야 합니다. 이 과정을 DNS 조회(DNS Lookup)라고 합니다. 브라우저는 먼저 캐시된 DNS 기록을 확인하고, 없는 경우 DNS(Domain Name System) 서버에 쿼리를 보냅니다. DNS 서버는 도메인 이름을 IP 주소로 변환하여 브라우저에 반환합니다.

브라우저는 IP 주소를 통해 서버와 TCP 연결을 시도합니다. TCP(Transmission Control Protocol)는 데이터를 신뢰성 있게 전달하기 위한 프로토콜입니다. 이 과정에서 브라우저와 서버는 3-way handshake를 수행합니다. 브라우저는 서버에 SYN 패킷을 보내고, 서버로부터 SYN-ACK를 받은 후 ACK를 전송해 TCP 연결을 확립합니다.

TCP 연결이 확립되면 브라우저는 해당 IP 주소를 통해 서버에 GET 또는 POST 등의 HTTP/HTTPS 요청을 보냅니다. 만약 HTTPS를 사용하는 경우, 이 단계 이전에 SSL/TLS handshake를 수행합니다. 이 과정에서는 TLS 버전, 암호화 알고리즘 협상, 서버 인증서 검증, 세션 키 교환 등을 수행해 대칭 암호화를 위한 세션 키를 생성합니다. HTTP/HTTPS 요청을 받은 서버는 HTML 문서와 함께 CSS, JavaScript, 이미지 등 웹 페이지를 구성하는 모든 리소스를 클라이언트로 전달합니다.

pic1

pic2

Step 2 - HTML 파싱 및 DOM 트리 생성

브라우저는 다운로드한 HTML 문서를 파싱하여 DOM 트리를 생성합니다. 이때, HTML 태그를 노드로 변환하고, 노드 간의 계층 관계를 형성합니다. 이 과정은 HTML 문서의 위에서 아래 방향으로 이루어집니다.

만약 HTML 파싱 중에 asyncdefer 같은 설정이 되어있지 않은 <script> 태그를 만나는 경우 HTML 파싱을 일시 중단하고 자바스크립트를 실행하게 됩니다. 또한 외부 CSS 파일을 만나는 경우 CSSOM 생성 전까지 렌더링이 지연됩니다.

Info.
DOM은 Document Object Model으로 XML이나 HTML 문서에 접근하기 위한 인터페이스입니다. DOM은 자바스크립트로 접근하여 수정될 수 있습니다.

Tips
script 태그에서 async 속성 또는 defer 속성을 사용하면 스크립트를 비동기적으로 다운로드하므로 HTML 파싱과 병렬적으로 수행할 수 있습니다. 이 둘은 자바스크립트 실행 시점에서 차이가 있습니다. 실행 순서가 중요하거나 애플리케이션의 로직을 담고 있는 스크립트인 경우 defer를, 독립적으로 실행되는 스크립트인 경우 async를 사용하는 것이 적절합니다.

async: async 속성을 사용하면 스크립트를 백그라운드에서 다운로드한 후 다운로드가 완료되면 즉시 실행합니다. (스크립트 실행 중에는 HTML 파싱이 일시 중지됩니다.) 여러 async 스크립트가 있는 경우, 다운로드가 완료되는 순서대로 자바스크립트를 실행합니다.
defer: defer 속성을 사용하면 스크립트를 백그라운드에서 다운로드한 후 HTML 파싱이 완료된 후(모든 DOM이 로드된 후) 자바스크립트를 실행합니다. (DOMContentLoaded 이벤트가 발생하기 전에 실행됩니다.) 여러 defer 스크립트가 있는 경우, HTML에 작성된 순서대로 자바스크립트를 실행합니다.

Step 3 - CSS 파싱 및 CSSOM 트리 생성

HTML 파싱과 DOM 트리 생성이 완료되면, 브라우저는 다운로드한 CSS 파일을 파싱하여 CSSOM(CSS Object Model) 트리를 생성합니다. 이때, CSS 속성을 노드로 변환하고 노드 간의 계층 관계를 형성합니다. 이 과정에서 브라우저는 CSS의 cascading 규칙에 따라 최종 스타일을 결정합니다.

Info.
CSSOM(CSS Object Model)은 CSS 객체 모델로 자바스크립트가 CSS를 동적으로 조작할 수 있게 해줍니다. HTML 대신 CSS가 대상인 DOM이라고 할 수 있습니다.

Step 4 - 렌더 트리 생성

DOM 트리CSSOM 트리를 결합하여 렌더 트리를 생성합니다. 이때, 실제 화면에 표시될 요소만을 선택하여 렌더 트리를 형성합니다. 즉, display: none 속성이 적용된 요소는 렌더 트리에 포함되지 않습니다. 반면에 visibility: hidden 속성이 적용된 요소는 공간을 차지하므로 렌더 트리에 포함됩니다.

렌더 트리의 각 노드는 DOM 트리의 요소와 연결되며, CSSOM 트리에서 해당 요소에 적용된 스타일 정보를 포함합니다. 즉, 렌더 트리는 HTML 문서의 구조와 각 요소의 스타일 정보를 모두 포함한 트리입니다.

Step 5 - 레이아웃/리플로우(Layout/Reflow)

렌더 트리가 생성되면 각 노드의 정확한 위치와 크기를 계산하는 레이아웃(또는 리플로우) 단계가 시작됩니다. 이 과정에서 상대적 단위(%, em, rem 등)를 실제 px 단위로 변환하며, 요소의 박스 모델(margin, border, padding, content)을 고려하여 최종 배치가 결정됩니다.

Info.
박스 모델(Box Model)은 모든 HTML 요소는 박스(Box) 형태의 영역으로 이루어져 있다는 개념입니다. 박스(Box)는 마진(margin), 테두리(border), 패딩(padding), 내용(content)로 구분됩니다.

Step 6 - 페인팅(Painting)

브라우저는 계산된 레이아웃 정보를 바탕으로 각 요소를 실제 화면에 그리는 페인팅 단계를 실행합니다. 이 때, 각 요소의 배경, 테두리, 글자 등을 그리게 됩니다. 이 과정에서 브라우저는 성능 최적화를 위해 요소를 독립적인 레이어(Layer)로 분리하여 렌더링합니다. 이는 성능 저하를 초래할 수 있는 레이아웃 스래싱(Layout Thrashing)을 방지하기 위함입니다.

Info.
레이아웃 스레싱(Layout Thrashing)이란 웹 페이지에서 JavaScript가 반복적으로 DOM을 읽고 쓰는 작업을 수행할 때, 브라우저가 불필요하게 레이아웃 계산을 여러 번 강제로 실행하며 성능이 급격히 저하되는 현상을 말합니다.

Step 7 - 합성(Composite)

이 단계에서는 여러 레이어(Layer)를 합성하여 최종 화면을 출력합니다. 이 때, GPU와 합성 스레드가 협력하여, 스크롤이나 애니메이션 시 부드러운 업데이트를 가능하게 합니다. transform, opacity 속성은 GPU 가속을 지원하며 별도 레이어에서 처리되어 리플로우를 일으키지 않고 애니메이션이 가능합니다.

Step 8 - 리렌더링

리렌더링이 발생하면 리플로우(Reflow)리페인트(Repaint)가 발생합니다.

  • 리플로우(Reflow)

    웹 페이지 내에서 요소의 위치 또는 크기에 변화가 있는 경우, 즉 DOM이나 CSSOM에 변경이 발생하면, 영향을 받는 부분에 대해 다시 레이아웃 계산이 필요합니다. 이 경우, 변경된 부분에 대해 다시 렌더 트리를 구성하고 레이아웃 및 페인팅 단계, 합성도 다시 수행됩니다. 예를 들어, 요소의 크기, 위치, margin 등이 변경될 때 리플로우가 발생하며, 이 경우 페인팅과 합성도 다시 수행됩니다. width, height, padding, margin, border-width와 같은 크기 관련 속성, position, top, left와 같은 위치 관련 속성, display, flex 속성과 같은 레이아웃 관련 속성, font-size, font-weight와 같은 폰트 크기 관련 속성이 리플로우를 유발하는 속성입니다.

  • 리페인트(Repaint)

    레이아웃 변화 없이 색상, 배경 등 스타일만 변경되면 리페인트만 일어나며, 레이아웃 재계산없이 다시 화면을 그립니다. color, background-color와 같은 색상 관련 속성, border-color, border-radius와 같운 테두리 관련 속성이 리페인트를 유발하는 속성입니다.

Tips
리플로우와 리페인트는 웹 페이지가 렌더링되는 과정에서 발생하는 중요한 작업들로, 이 둘을 잘 관리하는 것이 성능 최적화에 도움이 됩니다.
성능 최적화를 위한 방법으로는 다음 3가지를 고려할 수 있습니다.

- 리플로우를 유발하는 CSS 속성 사용 최소화하기
width, height, margin, border, padding 등 리플로우를 유발하는 속성의 사용을 최소화하는 것이 좋습니다.
- CSS 애니메이션 최적화
transform과 opacity 속성은 GPU 가속을 사용할 수 있어 리플로우를 일으키지 않고 리페인트만 발생시키므로 CPU 자원을 적게 사용합니다.
- will-change 속성 사용
will-change 속성은 요소의 변화를 미리 브라우저에게 알려주어 브라우저가 GPU 가속을 활용하여 최적화하는 데 도움을 줍니다. 단, will-change 속성을 너무 많이 사용하면 오히려 성능이 저하될 수 있으므로 주의해야 합니다.

참고 자료

This post is licensed under CC BY 4.0 by the author.