alpaka206

브라우저 렌더링 파이프라인 정리

date
Dec 15, 2025
slug
browser-rendering-pipeline
author
status
Public
tags
Study
summary
type
Post
thumbnail
category
💻 Frontend
updatedAt
Dec 24, 2025 04:25 AM
“왜 느리지?”, “왜 깜빡이지?”, “왜 스크롤이 버벅이지?” 같은 문제는 대부분 렌더링 파이프라인과 연결되어 있기에, 프론트에서 성능 이슈를 만나면 결국 브라우저 렌더링으로 돌아오게 됩니다.
이번 글에서는 URL을 입력하고 페이지가 보이기까지의 과정부터 브라우저가 화면을 그리는 파이프라인, 그리고 Reflow와 Repaint 차이 및 왜 transform / opacity가 리플로우를 피하는지를 제 기준대로 정리해보고자 합니다

URL 치고 첫 화면이 보이기까지 (네이버 예시)

크롬 주소창에 http://www.naver.com을 입력했다고 가정합니다.

(1) Navigation 시작 + URL 파싱

브라우저는 네비게이션을 시작하고 입력 문자열을 URL로 파싱합니다. 이 과정에서 보안 정책도 함께 적용됩니다.
  • HSTS 목록이 있으면 httphttps로 업그레이드
  • HTTPS만 허용하는 정책이면 강제로 HTTPS로 이동

(2) 캐시 확인 (생략 가능한 단계 찾기)

네트워크 요청 전에 캐시를 먼저 확인합니다.
  • HTTP 캐시: HTML/CSS/JS/이미지/폰트 같은 리소스가 남아있을 수 있음
  • DNS 캐시: 도메인 → IP 결과가 있으면 DNS 질의 자체를 생략 가능
캐시에 필요한 리소스가 충분히 있다면, 네트워크를 거의 타지 않고도 렌더링이 가능합니다.

(3) DNS → IP 변환

캐시에 없다면 DNS 질의를 통해 도메인을 IP로 변환합니다.
  • www.naver.comxxx.xxx.xxx.xxx

(4) 서버 연결 (TCP + TLS)

IP를 얻으면 서버와 연결합니다.
  • TCP 핸드셰이크
  • HTTPS라면 TLS 핸드셰이크까지
연결이 끝나면 HTTP 요청을 보낼 수 있습니다.

(5) HTML 요청 / 리다이렉트 처리

브라우저는 HTML 문서를 요청합니다.
  • 301/302 같은 리다이렉트가 오면 Location 헤더의 URL로 다시 이동
  • 이동하면 DNS/연결/요청 과정이 다시 반복될 수 있음

(6) HTML 응답 수신 → 스트리밍 파싱 시작

HTML은 다 받을 때까지 기다리지 않고 스트리밍으로 파싱합니다.
  • 파싱하면서 DOM을 생성
  • 동시에 preload scanner<link>, <script>, <img> 같은 리소스를 미리 찾아 요청을 앞당김
여기서부터 렌더링 파이프라인이 본격적으로 시작됩니다.

2) 브라우저 렌더링 파이프라인 (DOM → 화면)

브라우저가 화면을 그릴 때의 흐름은 보통 다음과 같습니다.
DOM 생성 → CSSOM 생성 → Render Tree → Layout → Paint → Composite

(1) DOM 생성 (HTML 파싱)

HTML을 파싱해서 DOM 트리를 만듭니다.
  • 태그 구조가 트리로 변환됨
  • <script>를 만나면 HTML 파싱이 멈출 수 있음

(2) CSSOM 생성 (CSS 파싱)

CSS를 파싱해 CSSOM을 만듭니다.
CSS는 보통 렌더링 블로킹입니다.
  • CSSOM이 없으면 스타일 없는 화면이 먼저 보일 수 있음
  • 이를 피하려고 브라우저는 CSS를 빠르게 받고, 준비되기 전에는 최초 렌더를 지연하기도 합니다.

(3) Render Tree 생성

DOM + CSSOM을 결합해 실제로 화면에 그릴 노드만 뽑아 Render Tree를 만듭니다.
  • display: none → Render Tree에 포함되지 않음
  • visibility: hidden → 공간은 차지하므로 포함됨

(4) Layout (Reflow)

각 요소의 위치와 크기를 계산합니다.
  • “이 div는 (x, y)에 있고 width/height는 얼마” 같은 기하 계산
  • 글꼴, 줄바꿈, 부모-자식 관계 등 연쇄 영향이 많아서 비용이 커질 수 있음

(5) Paint (Repaint)

Layout 결과를 기반으로 픽셀을 칠합니다.
  • 배경색, 텍스트, 보더, 그림자, 이미지 등을 실제로 칠함

(6) Composite (합성)

레이어로 분리된 요소들을 GPU에서 합성해 최종 화면을 만듭니다.
  • 이 단계에서 끝나면 레이아웃/페인트 없이 화면 갱신이 가능해 비용이 줄어듦
  • transform / opacity가 주로 여기서 처리되기 쉬워 애니메이션 성능이 잘 나오는 경우가 많음

3) Reflow는 언제 발생하나?

Reflow(Layout)는 요소의 크기/위치 계산이 다시 필요할 때 발생합니다.
  • width, height 변경
  • margin, padding 변경
  • display 변경 (none, block, flex 등)
  • DOM 추가/삭제
  • 폰트 크기 변경(줄바꿈 영향)
  • 부모 컨테이너 크기 변경 (자식 레이아웃 연쇄 영향)

4) Reflow 비용이 큰 이유

Reflow는 특정 요소 하나만 다시 계산하는 작업이 아닙니다.
어떤 요소의 크기/위치가 바뀌면
  • 부모 크기가 달라질 수 있고
  • 형제 위치가 밀릴 수 있고
  • 자식 배치가 달라질 수 있습니다.
즉, 레이아웃 트리의 상당 부분을 연쇄적으로 다시 계산해야 해서 비용이 큽니다.
특히 리스트/테이블/복잡한 레이아웃에서 더 크게 발생합니다.

5) Reflow vs Repaint 차이

  • Reflow(Layout): 위치/크기 재계산
  • Repaint(Paint): 픽셀 다시 칠하기
보통 Reflow가 발생하면 Repaint도 뒤따르는 경우가 많지만, Repaint는 Reflow 없이도 발생할 수 있습니다.
  • color: red → Repaint만
  • width: 200px → Reflow + Repaint(대부분)

6) transform / opacity는 왜 Reflow가 없나?

transform / opacity는 레이아웃 계산에 영향을 주지 않습니다.
  • transform은 레이아웃 위치를 바꾸는 게 아니라, 이미 계산된 결과 위에서 레이어를 이동시키는 방식에 가깝습니다.
  • opacity는 투명도만 바꾸는 것이기 때문에 Layout 재계산이 필요 없습니다.
그래서 애니메이션은 보통
transform, opacity
top/left, width/height
쪽이 유리합니다.

7) 실무에서 자주 나오는 케이스

케이스 1) 스크롤이 버벅인다

  • 스크롤 이벤트에서 DOM 스타일 변경을 계속 함
  • 그 변경이 Layout을 반복적으로 유발함
  • 메인 스레드가 Layout/Paint로 바빠져 프레임 드랍 발생

케이스 2) 애니메이션이 끊긴다

  • left로 이동시키면 레이아웃 영향 → Reflow 가능성 증가
  • transform: translate(...)로 바꾸면 Composite로 처리되어 부드러워질 때가 많음