Critical rendering path는 browser가 resource를 받아 화면을 그리는 과정입니다. HTML을 파싱해서 DOM을 만들고, CSS를 파싱해서 CSSOM을 만듭니다. 그 다음 실제 화면에 필요한 node와 style을 합쳐 render tree를 만들고, 각 요소의 위치와 크기를 계산하는 layout을 수행합니다.
이후 pixel을 채우는 paint와 layer를 합치는 composite 과정을 거쳐 화면에 표시됩니다. CSS는 render-blocking resource가 될 수 있고, JavaScript는 DOM/CSSOM에 접근할 수 있기 때문에 parsing을 막을 수 있어 로딩 성능에서 중요합니다.
꼬리질문
조금 더 깊게 물어본다면
답변 뒤에 이어질 수 있는 질문들을 하나씩 열어볼 수 있어요.
DOM과 render tree는 같은 건가요?
같지 않습니다. DOM은 HTML 문서 구조를 나타내고, render tree는 실제 화면에 그릴 node와 계산된 style을 포함합니다. display: none인 요소는 DOM에는 있지만 render tree에는 포함되지 않을 수 있습니다.
이 차이를 알아야 “DOM에 있다”와 “화면에 그려진다”를 구분할 수 있습니다.
layout과 paint는 어떻게 다른가요?
layout은 요소의 위치와 크기를 계산하는 단계입니다. paint는 계산된 box를 실제 pixel로 채우는 단계입니다.
width, height, position 변경은 layout을 유발할 수 있고, color 변경은 layout 없이 paint만 필요할 수 있습니다.
JavaScript가 rendering을 막을 수 있는 이유는 무엇인가요?
JavaScript는 DOM을 읽거나 수정할 수 있고, style 정보에 의존할 수도 있습니다. 그래서 browser는 script 실행 순서를 보장하기 위해 parsing을 멈출 수 있습니다.
defer, async, code splitting 같은 전략이 로딩 성능과 연결됩니다.
reflow와 repaint는 어떤 차이가 있나요?
reflow는 layout을 다시 계산하는 작업을 의미하는 경우가 많고, repaint는 pixel을 다시 그리는 작업입니다. layout이 바뀌면 보통 paint도 이어질 수 있어 더 비쌉니다.
요즘은 용어보다 layout/paint/composite 단계로 설명하는 편이 더 명확할 수 있습니다.
부가 설명
HTML -> DOMCSS -> CSSOMDOM + CSSOM -> Render TreeRender Tree -> Layout -> Paint -> Composite
각 단계는 서로 영향을 줍니다. 예를 들어 CSS가 늦게 오면 style을 계산하기 어렵고, JavaScript가 DOM을 바꾸면 layout이 다시 필요할 수 있습니다.
성능 최적화에서는 “무엇이 첫 화면 렌더링을 막고 있는가”를 봅니다. 큰 CSS 파일, parser를 막는 script, layout을 자주 유발하는 DOM 조작은 critical rendering path를 길게 만들 수 있습니다.
Browser 렌더링 파이프라인은 구현마다 세부가 다를 수 있습니다. 그래서 핵심은 큰 흐름과 병목 지점을 구분하는 데 있습니다.
한 줄 정리
critical rendering path는 browser가 DOM, CSSOM, render tree를 만들고 layout과 paint를 거쳐 화면을 그리는 핵심 경로입니다.