에듀테크 프로젝트 대시보드
브라우저 렌더링 파이프라인
아래 단계를 클릭하거나 ▶ 단계 실행 버튼으로 하나씩 진행해 보세요. 각 단계에서 브라우저가 실제로 무슨 일을 하는지 설명이 나옵니다.
브라우저는 HTML을 읽어 DOM 트리를, CSS를 읽어 CSSOM 트리를 만듭니다.
이 둘을 합쳐 실제로 화면에 그려질 노드만 모은 것이 Render Tree입니다.
display:none 인 요소는 Render Tree에서 빠지고,
visibility:hidden 은 자리는 차지하므로 남습니다.
<!-- HTML --> <body> <h1>제목</h1> <p>본문</p> <footer>비밀</footer> </body>
/* CSS */ h1 { color: navy; } p { font-size: 16px; } footer { display: none; }
<head> 안의 큰 CSS 파일은 첫 화면을 늦춥니다.
(이 사이트의 base.html 도 Font Awesome을 media="print" 트릭으로 비동기 로드해서 이 차단을 피합니다.)
화면이 이미 그려진 뒤 JS로 스타일을 바꾸면, 바꾼 속성에 따라 브라우저가 되돌아가는 단계가 다릅니다. 아래 버튼으로 박스의 스타일을 바꿔 보면서, 어떤 단계가 다시 도는지 카운터로 확인해 보세요.
| 바꾼 속성 | 다시 도는 단계 | 비용 |
|---|---|---|
width, top, font-size, DOM 추가/삭제 |
Layout → Paint → Composite | 비쌈 (형제·자식 위치 재계산) |
background, color, box-shadow, visibility |
Paint → Composite | 중간 |
transform, opacity (GPU 레이어) |
Composite 만 | 쌈 (GPU가 처리, 60fps 애니메이션에 유리) |
left/top 대신
transform: translate() 를, 페이드는 opacity 를 쓰세요.
Layout·Paint를 건너뛰고 Composite만 돌아서 훨씬 부드럽습니다.
<script> 를 만나면 브라우저는 DOM 파싱을 멈추고 스크립트를 내려받아 실행합니다.
스크립트가 document.write 로 DOM을 바꿀 수도 있기 때문입니다.
그래서 <head> 안의 일반 스크립트는 첫 화면을 크게 늦춥니다.
| 선언 | 다운로드 | 실행 시점 | 순서 보장 |
|---|---|---|---|
<script> | 파싱 멈춤 | 즉시 (파싱 차단) | O |
<script defer> | 병렬 | 파싱 끝난 뒤, DOMContentLoaded 직전 | O |
<script async> | 병렬 | 다운로드 되는 즉시 (파싱 중이라도) | X |
<!-- 권장: 본문을 막지 않고, DOM 완성 후 순서대로 실행 --> <head> <script src="/static/app.js" defer></script> </head>
offsetWidth 같은 값을 읽어 강제 동기 Reflow를 여러 번 일으키는 안티패턴.transform/opacity 애니메이션을 GPU로 처리하는 스레드.