브라우저 렌더링 최적화 심화 (Layout · Composite · GPU Rendering)
Reference
앞선 글에서 렌더링이 DOM + CSSOM → Render Tree → Layout → Paint → Composite
과정을 살펴봤다. 이번 글에서는 이 과정이 브라우저 내부의 스레드와 GPU에서 어떻게 실행되는지, 그리고 왜 transform과 opacity가 성능 친화적 속성으로 불리는지 찾아보게따 👀 !
1. 브라우저 렌더링 파이프라인의 내부 구조
렌더링은 단순히 DOM을 그리는 게 아니라, 여러 스레드(thread)
와 프로세스(process)
가 협력하는 복잡한 그래픽 시스템이다.
Main Thread
├─ HTML 파싱 → DOM 생성
├─ CSS 파싱 → CSSOM 생성
├─ Render Tree → Layout → Paint
└─ Layer 분리 (Composite 준비)
↓
Compositor Thread
├─ 레이어 합성 (Composite)
└─ GPU에 렌더링 명령 전달
↓
GPU Process
└─ 실제 픽셀 렌더링 (GPU Rasterization)
스레드 | 역할 | 주요 작업 |
---|---|---|
Main Thread | 렌더링의 핵심 처리 | JS 실행, DOM/CSSOM, Layout, Paint |
Compositor Thread | GPU와 협력해 합성 처리 | Layer 관리, 스크롤·애니메이션, GPU 명령 전달 |
GPU Process | 실제 픽셀 렌더링 | 레이어 rasterize 및 최종 프레임 출력 |
💡 즉, 브라우저는 Main Thread
에서 계산된 Layout과 Paint 정보를 Compositor Thread → GPU
로 넘겨 병렬 합성(Rendering)
을 수행한다.
2. Main Thread: 렌더링의 중심
렌더링의 시작점은 Main Thread
다.
단계 | 설명 | 주요 작업 |
---|---|---|
DOM/CSSOM 생성 | HTML·CSS 파싱 | 구조·스타일 계산 |
Layout (Reflow) | 각 노드의 크기·좌표 계산 | 위치 재계산 (Reflow 발생 가능) |
Paint | 각 노드의 스타일 속성을 픽셀로 변환 | 색상·그림자·테두리 등 |
Layer 분리 | GPU 합성용 레이어로 승격 | transform, opacity 등 |
💡 Main Thread는 자바스크립트 실행과 Layout/Paint를 함께 담당하기 때문에, JS 연산이 무거우면 렌더링 프레임(60fps)에 직접적인 영향을 준다.
3. Compositor Thread와 GPU Thread
Layout과 Paint는 CPU에서 처리되지만, 합성(Compositing)은 GPU에서 수행된다. 이 단계는 화면을 실제로 움직이게 하는
핵심이다.
Main Thread → Paint 결과 전달
Compositor Thread → 레이어 이동(transform, opacity)
GPU Thread → 최종 픽셀 합성
💡 transform / opacity 속성이 빠른 이유는, Layout, Paint를 건너뛰고 Compositor + GPU 단계
에서만 처리되기 때문이다.
4. Layout · Paint · Composite의 역할 비교
단계 | 주 담당 | 특징 | 대표 속성 |
---|---|---|---|
Layout | CPU | 좌표·크기 계산 (Reflow) | width, height, top, left |
Paint | CPU | 색상·경계선 등 픽셀 채색 | color, background, border |
Composite | GPU | 이미 그려진 비트맵을 합성 | transform, opacity |
💡 Layout과 Paint는 CPU 기반, Composite는 GPU 기반이다.
따라서 Reflow·Repaint보다 Composite만 유발하는 변경이 훨씬 가볍다.
5. Layer(합성 레이어)의 개념
브라우저는 특정 조건의 요소를 별도의 Compositing Layer
로 승격시킨다. 이 레이어는 GPU에서 독립적으로 처리되므로, 다른 요소의 Layout에 영향을 주지 않는다.
레이어 승격 조건 | 예시 | 비고 |
---|---|---|
transform / opacity 사용 | transform: translateX(100px) | 가장 권장되는 방법 |
3D 속성 사용 | translateZ(0) | 강제 레이어 승격 트릭 |
will-change 지정 | will-change: transform | 사전 최적화 힌트 |
position: fixed / video / canvas | 고정·미디어 요소 | 자동 레이어 승격 |
backface-visibility: hidden | backface-visibility: hidden | 레거시 트릭 (비권장) |
이런 요소는 GPU가 직접 처리하기 때문에 스크롤, 회전, 애니메이션이 매우 부드럽게 동작한다.
💡 backface-visibility: hidden
은 과거 레이어 승격을 강제하기 위해 쓰였으나, 요즘은 will-change
나 transform: translateZ(0)
가 더 명시적이고 권장된다.
6. GPU 합성과 렌더링 최적화
GPU가 유리한 이유
GPU는 픽셀 렌더링을 병렬로 수행할 수 있어, opacity·transform처럼 픽셀 재계산 없이 이동/회전
하는 작업에 최적화되어 있다.
하지만 주의할 점도 있다:
- 너무 많은 레이어는 GPU 메모리를 과도하게 사용
- 레이어 합성 단계가 늘어나면 오히려 렌더링 병목 발생
💡 핵심은 필요한 요소만 GPU에 맡기기다.
7. GPU 합성 시각화
[Main Thread]
├─ Layout (DOM → Box 계산)
├─ Paint (비트맵 생성)
▼
[Compositor Thread]
├─ Layer Tree 관리
├─ 스크롤 / transform 처리
▼
[GPU]
└─ 레이어 병합 (Rasterize → Composite → Display)
💡 Layout/Paint는 CPU에서, Composite는 GPU에서.
즉, JS 연산을 줄이고 GPU 처리로 넘길수록 부드럽다.
8. 렌더링 최적화를 위한 팁
전략 | 설명 | 주의사항 |
---|---|---|
GPU 친화적 속성 사용 | transform / opacity로 애니메이션 | top/left는 Reflow 유발 |
will-change 사용 | 미리 GPU 레이어로 준비 | 남용 시 메모리 낭비 |
CSS 필터 최소화 | filter, box-shadow는 Paint 비용 ↑ | 꼭 필요할 때만 사용 |
JS 애니메이션 최적화 | requestAnimationFrame() 사용 | setInterval보다 부드럽다 |
// requestAnimationFrame은 브라우저의 repaint 타이밍(보통 60fps)에 맞춰 실행되므로
// setTimeout/setInterval보다 프레임 드롭 없이 부드러운 애니메이션 구현 가능
function animate() {
box.style.transform = `translateX(${x++}px)`;
requestAnimationFrame(animate); // 다음 프레임에 맞춰 자동 호출
}
animate();
💡 requestAnimationFrame
은 브라우저가 다음 화면을 그리기 직전에 콜백을 실행하므로, 불필요한 렌더링을 방지하고 배터리 소모도 줄인다..
9. CPU → GPU로의 최적화 이동
렌더링 최적화의 본질은 CPU 중심에서 GPU 중심으로의 이동
이다.
(메인 스레드의 일을 줄이고, GPU로 오프로드 하는 것)
Main Thread 부하 ↓
Compositor/GPU 처리 ↑
→ 안정적인 60fps 프레임 유지
단계 | 주 담당 | 성능 영향 | 비고 |
---|---|---|---|
Layout | CPU | 높음 | Reflow 발생 |
Paint | CPU | 중간 | Repaint |
Composite | GPU | 낮음 | GPU 합성 |
GPU Rendering | GPU | 가장 효율적 | transform / opacity 중심 |
💡 요약
- 브라우저는 Main Thread → Compositor Thread → GPU Process로 렌더링 파이프라인을 분리한다.
- transform, opacity, will-change 속성은 GPU 합성 단계에서 처리되어 Reflow를 방지한다.
- CPU 기반 Layout/Paint를 최소화하면 GPU가 더 많은 작업을 병렬로 처리할 수 있다.
- 최적화의 핵심: Main Thread 부하 ↓, GPU 합성 ↑, 60fps 유지.