렌더링이란?
렌더링은 HTML, CSS 코드(텍스트)를 브라우저가 읽어서 우리 눈에 보이는 화면으로 바꾸는 과정입니다.
전체 흐름
① HTML 파싱 → DOM 트리
② CSS 파싱 → CSSOM 트리
↓
③ 둘을 합침 → Render Tree
↓
④ Layout → 위치/크기 계산
↓
⑤ Paint → 색칠
↓
⑥ Composite → 최종 화면 출력
1. DOM 트리 (Document Object Model)
브라우저가 HTML을 읽고 트리 구조로 변환한 것입니다.
JS에서 document.querySelector로 요소를 찾을 수 있는 것도 DOM 덕분입니다.
<!-- HTML -->
<html>
<body>
<div>
<h1>제목</h1>
<p>내용</p>
</div>
</body>
</html>
<!-- DOM 트리 구조 -->
html
└── body
└── div
├── h1 ("제목")
└── p ("내용")
부모-자식 관계로 계층 구조를 이루며, 각 요소가 하나의 노드(Node)가 됩니다.
2. CSSOM 트리 (CSS Object Model)
브라우저가 CSS를 읽고 DOM 트리와 동일하게 트리 구조로 변환한 것입니다.
/* CSS */
body { font-size: 16px; }
h1 { color: red; }
p { color: blue; }
/* CSSOM 트리 구조 */
body (font-size: 16px)
├── h1 (color: red)
└── p (color: blue)
부모 요소의 스타일이 자식에게 상속되는 CSS 특성도 CSSOM 트리에 반영됩니다.
3. Render Tree = DOM + CSSOM
DOM 트리(구조)와 CSSOM 트리(스타일)를 합쳐서 실제로 화면에 그릴 것들만 모은 트리입니다.
중요한 점은 화면에 보이지 않는 요소는 Render Tree에서 제외된다는 것입니다.
display: none → Render Tree에서 아예 제외
visibility: hidden → Render Tree에 포함되지만 투명하게 처리
4. Layout (Reflow)
Render Tree를 바탕으로 각 요소의 위치와 크기를 계산하는 단계입니다.
width, height, margin, padding 같은 값이 바뀌면 이 계산을 처음부터 다시 해야 해서 비용이 가장 큽니다.
5. Paint (Repaint)
Layout에서 계산한 위치에 실제로 색을 칠하는 단계입니다.
color, background, border 같은 스타일이 바뀌면 이 단계만 다시 실행되므로 Layout보다 가볍습니다.
6. Composite
Paint에서 그린 레이어들을 합쳐서 최종 화면을 완성하는 단계입니다.
transform, opacity를 사용하면 이 단계만 실행되어 가장 빠릅니다.
변경 발생 시 어디서부터 다시 실행될까?
| 변경 내용 | 재실행 단계 | 비용 |
|---|---|---|
| width, height, margin 변경 | Layout → Paint → Composite | 가장 큼 |
| color, background 변경 | Paint → Composite | 중간 |
| transform, opacity 변경 | Composite만 | 가장 작음 |
성능 최적화 팁
애니메이션 구현 시 left, top 대신 transform을 사용하면 Composite 단계만 실행되어 훨씬 부드럽고 빠릅니다.
/* 나쁜 예 - Layout부터 재실행 */
.box { left: 100px; }
/* 좋은 예 - Composite만 실행 */
.box { transform: translateX(100px); }
정리
브라우저는 HTML과 CSS를 각각 파싱해 DOM 트리와 CSSOM 트리를 만들고, 이 둘을 합쳐 Render Tree를 구성합니다. 이후 Layout에서 위치와 크기를 계산하고, Paint에서 색을 칠한 뒤 Composite에서 최종 화면을 출력합니다.
변경이 발생하면 변경된 단계부터 다시 실행되므로, 앞 단계일수록 비용이 크다는 점을 기억하면 성능 최적화에 도움이 됩니다.
'-- 오늘 있었던 개발 일기' 카테고리의 다른 글
| 객체지향 프로그래밍(OOP)이란? (0) | 2026.03.19 |
|---|---|
| 참조 타입(Reference Type)이란? (0) | 2026.03.14 |
| 동기(Sync)와 비동기(Async) (0) | 2026.02.20 |
| Redis 특징 완벽 정리! (0) | 2026.02.20 |
| Refresh Token을 HttpOnly Cookie로 변경한 이유! (0) | 2026.02.12 |