본문 바로가기
Frontend2025년 12월 5일5분 읽기

브라우저 렌더링 파이프라인 이해 — DOM CSSOM Paint Composite

YS
김영삼
조회 414

브라우저 렌더링 파이프라인 전체 흐름

사용자가 URL을 입력하면 브라우저는 HTML을 다운로드하고 복잡한 파이프라인을 거쳐 화면에 픽셀을 그립니다. 이 과정을 이해하면 성능 최적화의 핵심을 파악할 수 있습니다.

1단계: DOM 트리 생성

브라우저는 HTML 바이트를 토큰으로 변환하고, 토큰을 노드로 변환한 뒤, 노드를 트리 구조로 조합합니다.

// DOM 트리 구조 예시
document
  └─ html
      ├─ head
      │   ├─ meta
      │   └─ link (stylesheet)
      └─ body
          ├─ header
          │   └─ nav
          ├─ main
          │   ├─ article
          │   └─ aside
          └─ footer

2단계: CSSOM 생성

CSS 파일이 파싱되면 CSSOM(CSS Object Model)이 생성됩니다. CSSOM은 DOM과 유사한 트리 구조를 가지며, 각 노드에 스타일 정보가 포함됩니다.

/* CSSOM 계산 과정 */
body { font-size: 16px; }
  → main { font-size: 16px; } /* 상속 */
    → article { font-size: 16px; } /* 상속 */
      → p { font-size: 16px; line-height: 1.6; } /* 상속 + 자체 */

/* 렌더 차단 리소스 */
<link rel="stylesheet" href="style.css">  /* 렌더 차단 */
<link rel="stylesheet" href="print.css" media="print">  /* 차단 안함 */

3단계: 렌더 트리 구성

DOM과 CSSOM을 결합하여 렌더 트리를 생성합니다. display: none인 요소는 렌더 트리에서 제외됩니다.

4단계: Layout (Reflow)

렌더 트리의 각 노드에 대해 뷰포트 내 정확한 위치와 크기를 계산합니다.

// Layout을 유발하는 속성들
// 높은 비용: width, height, top, left, margin, padding, border
// display, position, float, overflow

// Layout을 피하는 최적화
// transform: translateX(100px)  → Layout 건너뜀
// left: 100px                   → Layout 발생

// 강제 동기 레이아웃 예시 (안티패턴)
element.style.width = '100px';
const height = element.offsetHeight; // 강제 레이아웃 발생!
element.style.height = height + 'px';

5단계: Paint

레이아웃 계산이 끝나면 각 레이어에 픽셀을 채웁니다. 텍스트, 색상, 이미지, 보더, 그림자 등을 그리는 단계입니다.

속성LayoutPaintComposite
width/heightOOO
color/backgroundXOO
transform/opacityXXO

6단계: Composite

여러 레이어를 GPU에서 합성하여 최종 화면을 생성합니다. transformopacity는 이 단계에서만 처리되므로 매우 빠릅니다.

/* GPU 가속 레이어 생성 */
.animated-element {
  will-change: transform;  /* 새 레이어 생성 힌트 */
  transform: translateZ(0); /* 레이어 승격 (핵 기법) */
}

/* 최적화된 애니메이션 */
.slide-in {
  /* 나쁨: left 사용 (Layout → Paint → Composite) */
  /* left: 0 → left: 100px */

  /* 좋음: transform 사용 (Composite만) */
  transform: translateX(0);
  transition: transform 0.3s ease;
}
.slide-in.active {
  transform: translateX(100px);
}

성능 측정 도구

  • Chrome DevTools Performance 탭에서 렌더링 파이프라인 각 단계의 소요 시간 확인
  • Rendering 탭에서 Paint flashing, Layout shift regions 시각화
  • Lighthouse의 CLS(Cumulative Layout Shift) 지표로 레이아웃 안정성 측정
  • requestAnimationFrame을 활용한 프레임 단위 최적화

핵심 최적화 전략

  • 애니메이션에는 transformopacity만 사용하여 Composite 단계에서 처리
  • will-change 속성을 적절히 사용하되 남용하지 않기
  • 강제 동기 레이아웃(Forced Synchronous Layout) 패턴 회피
  • DOM 배치 읽기/쓰기를 분리하여 레이아웃 스래싱 방지
  • CSS 포함(containment) 속성으로 레이아웃 범위 제한

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록