브라우저 렌더링 파이프라인
웹 브라우저는 URL 입력 한 번에 수십 개의 작업을 동시에 처리한다. pxd의 UX Engineer hongdoyoung은 "웹브라우저는 바쁘다"라는 글에서 브라우저가 HTML 문서를 받아 화면에 픽셀을 그리기까지의 렌더링 파이프라인 전 과정을 설명한다.
브라우저가 서버로부터 HTML을 수신하면 파싱(Parsing) 단계를 거쳐 DOM(Document Object Model) 트리를 생성한다. 동시에 CSS를 파싱하여 CSSOM(CSS Object Model) 트리를 만든다. 이 두 트리를 결합한 렌더 트리(Render Tree)는 실제로 화면에 표시될 요소만 포함하며, display: none 요소는 제외된다. 렌더 트리가 완성되면 레이아웃(Layout) 단계에서 각 요소의 위치와 크기를 계산하고, 페인트(Paint) 단계에서 픽셀을 그린다. 마지막으로 컴포지트(Composite) 단계에서 레이어를 합성하여 최종 화면을 완성한다.
성능 관점에서 핵심은 리플로우(Reflow)와 리페인트(Repaint)를 최소화하는 것이다. 리플로우는 요소의 크기나 위치가 변경될 때 레이아웃을 다시 계산하는 비용이 큰 작업이다. width, height, margin, padding, top, left 등의 CSS 속성 변경은 리플로우를 유발한다. 반면 color, background-color 등의 변경은 레이아웃 재계산 없이 리페인트만 발생시킨다. transform과 opacity는 컴포지트 레이어에서 처리되어 리플로우와 리페인트 모두 건너뛸 수 있어 애니메이션 성능에 유리하다.
Critical Rendering Path(중요 렌더링 경로)는 브라우저가 첫 화면을 그리기까지 거치는 최소 필수 단계다. HTML, CSS, JavaScript 중 하나라도 지연되면 렌더 블로킹(Render Blocking)이 발생하여 사용자가 빈 화면을 보게 된다. CSS는 기본적으로 렌더 블로킹 리소스이며, JavaScript는 DOM 조작 가능성 때문에 HTML 파싱을 중단시킨다. script 태그에 async나 defer 속성을 사용하면 파싱 차단을 방지할 수 있다.
핵심 내용
- 렌더링 파이프라인 순서: HTML 파싱 → DOM 생성 → CSSOM 생성 → 렌더 트리 → 레이아웃 → 페인트 → 컴포지트
- 리플로우는 레이아웃 재계산을 동반하는 고비용 작업 — transform 사용으로 우회 가능
- transform과 opacity는 GPU 컴포지트 레이어에서 처리되어 성능상 가장 효율적인 애니메이션 속성
- CSS와 JavaScript는 렌더 블로킹 리소스 — async/defer, 미디어 쿼리로 블로킹 최소화
- Critical Rendering Path 최적화가 초기 로딩 성능(FCP, LCP)에 직접적으로 영향을 미침
- JavaScript 실행은 DOM 파싱을 중단시키므로 script 태그 위치와 로딩 전략이 중요
관련 개념
- 웹 아키텍처 — 서버와 브라우저 사이의 요청/응답 구조
- 옵티미스틱 UI — 렌더링 지연을 체감상 줄이기 위한 UI 전략
- PWA 프로그레시브 웹 앱 — 렌더링 성능과 오프라인 경험 최적화
- CSS Flexbox — 레이아웃 계산에 관여하는 CSS 속성
출처
- 웹브라우저는 바쁘다 — 2025-04-21, hongdoyoung