잘못된 내용이 있다면 알려주시면 감사하겠습니다.
다음 글: https://so-tired.tistory.com/337
서론
최근에 웹 성능 최적화에 관심이 생기게 되었다.
그래서 React DevTools의 Highlight Updates 기능을 통해서 페이지의 렌더링을 개선하려던 와중, 해당 페이지의 상태가 변했을 때 상태를 사용하지 않는 정적인 컴포넌트에 하이라이트가 되는 이슈가 있었다.
사실 Highlight Updates 기능은 렌더 함수 실행 여부를 감지하기 때문에, 정적 컴포넌트에 변화가 없어도 변화 여부를 체크하기 위해 렌더 함수는 호출되기 때문에 하이라이트가 되는 것이 당연했다.
하지만 문득 아래와 같은 생각이 들었다.
"React를 통해 구현은 잘하고 있지만, 그 내부에서 일어나는 일들에 대해서 모호하게 알고 있구나."
"상태를 정말 필요한 위치에 선언하고 있나? 좀 더 명확한 관심사 분리를 통해 상태의 범위를 좁힐 수 있지 않았을까?"
더 깊은 생각을 하기 위해서는 다시 한번 기초를 다져야겠다는 생각이 들었고 첫 번째로 브라우저 렌더링 과정에 대해서 살펴 보기로 했다.
기본적으로 웹이 어떻게 렌더링 되는지 알아보자.
브라우저 렌더링 과정
브라우저 렌더링 과정(Critical Rendering Path)은 대부분의 프론트 개발자들이 알고 있듯이, 브라우저가 HTML, CSS, JavaScript를 화면에 픽셀로 그려내는 과정을 얘기한다.
1. 데이터 받아오기
클라이언트가 HTTP 요청을 서버로 보내면, 서버에서 일련의 처리를 거쳐 HTML을 생성한 후 응답 본문에 포함해 클라이언트로 전송한다.
(좀 더 자세한 CS 관점에서의 과정이 궁금하다면 해당 글을 참고하자.)
2. DOM 트리로 변환
브라우저는 서버로 부터 받은 HTML에 대한 byte stream을 분석하고 HTML로 변환해 DOM 트리를 생성하기 시작한다.
서버 응답: 바이트 스트림 (예: 0x48 0x54 0x4D 0x4C...)
→ 브라우저: 바이트 → 문자열 변환 ("HTML")
→ 토큰화: 문자열을 `<html>`, `</body>` 등 토큰으로 분해
→ 파싱: 토큰을 DOM 노드로 변환 (예: `<html>` → DOM 노드)
2-1. 추가 데이터 불러오기
브라우저는 스타일시트, 스크립트 또는 포함된 이미지 등의 외부 자원에 대한 링크를 찾을 때마다 자원을 요청한다.
불러온 에셋을 다룰 땐 DOM 트리를 생성하던 작업이 중단&차단 되기도 한다.
CSS 파일 요청 시
- DOM 생성 중단: <link> 태그 발견 시 HTML 파싱을 중단하고 CSS 파일 요청을 시작한다.
- DOM 재개: CSS 요청은 비차단적으로 처리되며, HTML 파싱은 CSS 요청 후 즉시 재개된다.
→ DOM은 CSSOM 완성 전에 완성되지 않지만, CSSOM이 완료되면 렌더링 차단이 발생한다.
JavaScript 요청 시
- DOM 생성 차단: <script> 태그 발견 시 HTML 파싱을 완전히 중단하고 JS 파일을 요청합니다
- DOM 재개 조건:
- 비차단적 스크립트(async/defer): JS 파일 요청 후 HTML 파싱 재개 → DOM은 JS 실행 전 완성된다.
- 차단적 스크립트(기본): JS 파일 요청 후 HTML 파싱 재개 불가 → DOM은 JS 실행 완료 후 완성된다.
이미지 요청 시
- DOM 생성 영향 없음: <img> 태그 발견 시 HTML 파싱 중단 없이 이미지를 요청한다.
- 이미지는 비동기적으로 로드된다.
2-2. CSSOM 생성
DOM 트리를 생성하다가 <link>태그 발견하게 되면, HTML 파싱을 중단하고 CSS 파일 요청을 시작한다.
그리고 CSSOM 트리는 DOM과 같은 방식으로 생성되며, CSSOM 트리가 생성되는 중에는 DOM 생성이 중단된다.
3. 렌더 트리 생성
DOM과 CSSOM이 완료되면, 브라우저는 렌더 트리를 생성하고 보이는 컨텐츠를 위해 스타일을 계산한다.
렌더 트리를 구성하기 위해 브라우저는 DOM 트리의 root에서 시작해 모든 노드를 확인하면서 어떤 CSS 규칙들을 첨부할지 결정한다.
렌더 트리는 렌더링을 위한 트리 구조의 자료구조다.
따라서 브라우저에 렌더링되지 않는 정보(헤드 섹션, 스크립트)나 CSS에 의해 비표시(display: none)되는 노드들은 포함되지 않는다.
즉, 렌더 트리는 브라우저 화면에 렌더링되는 노드만으로 구성된다.
4. Layout (리렌더링 시에는 Reflow)
Layout: 방에 가구를 처음 배치하는 것 → 비용은 높지만 한 번만
Reflow: 가구 하나를 움직일 때마다 주변 가구 위치를 재계산해야 함 → 지속적인 비용 발생
Layout은 브라우저가 각 요소를 화면에 어떻게 배치할지 위치나 크기를 계산하는 단계이다. Reflow는 요소의 변화로 인해 Layout 과정을 다시 수행하는 것이다.
다음과 같은 작업을 할 때 Reflow가 발생한다.
- DOM을 추가하거나 삭제할 때.
- css 속성중 높이, 넓이, 위치에 영향을 주는 속성 값을 변경할 때.
- Reflow를 일으키는 대표적인 속성: position, width, height, margin, padding, border, border-width, font-size, font-weight, line-height, text-align, overflow
Layout 성능은 DOM의 영향을 받는다.
DOM에 노드의 수가 많을수록 Layout의 수행이 길어지고 스크롤이나 애니메이션 시 버벅거림(jank)이 발생할 수 있다.
jank 현상이란?
일반적으로 디스플레이는 1초에 화면을 60번 그린다. (60 fps)
디스플레이가 1초에 60번 바뀌는데 웹페이지가 1초에 10번 그려진다면, 버벅거리는 현상이 발생한다.
이런 현상을 jank라고 부른다.
Layout은 초기 과정이라 반드시 일어나야 하지만 이 과정 자체가 비용이 많이 드는 단계이다 보니 잦은 Reflow가 발생하면 성능에 영향을 미친다. 왜냐면 Reflow가 발생하면 다음 단계까지 다시 이뤄지기 때문이다. (Reflow → Repaint)
5. Paint (리렌더링 시에는 Repaint)
Paint: 방에 가구를 배치한 후 벽을 처음 칠하는 것
Repaint: 기존의 칠한 벽의 색상을 변경하는 것
Paint은 브라우저가 요소의 색상, 배경, 그림자 등 시각적 스타일을 적용하고 화면에 픽셀을 그리는 단계이다.
Reflow는 요소의 스타일 요소가 변경되었을 때 다시 Paint를 수행하는 단계이다. (이때 요소의 레이아웃은 바뀌지 않는다.)
다음과 같은 작업을 할 때 Reflow가 발생한다.
- css 속성 중 높이, 넓이, 위치 등에 영향을 주지 않는 속성을 변경할 때 발생한다.
- 요소의 클래스가 변경되어 스타일이 변경될 때
- 브라우저 창이 활성화되거나 숨겨진 요소가 다시 표시될 때
- repaint만 일어나는 대표적인 속성: background, color, text-decoration, border-style, border-radius
Paint 단계에서는 우선
시각적 스타일(background-color, color, visibility 등)을 픽셀 단위로 변환한다.
(예: <div>의 background-color: blue → 파란색 픽셀 생성)
그 후 레이아웃 단계에서 계산된 위치/크기 정보를 기반으로 정확한 영역에 스타일 적용한다.
또한, z-index, position, opacity 등 속성에 따라 독립적인 레이어를 생성한다.
이러한 레이어 형태의 관리 덕분에 최소한의 리소스만 사용해 스타일을 변경할 수 있다.
확인해보기
간단한 HTML, CSS, JavaScript 코드를 작성해서 실행시켜 보았다.
개발자도구의 Performance → Event Log를 확인해 보면 이미지와 같이 렌더링 되는 과정을 확인해 볼 수 있다.
앞서 얘기한 브라우저 렌더링 과정과 흡사하다는 사실을 알 수 있다.
조금 의문이 갔던 부분이 있다면 JS의 요청은 DOM이 만들어지기 전에 이루어졌지만, JS의 실행은 Paint 이후에 이뤄졌다는 점이다.
이 부분에 대해서 GPT 한테 해답을 구하니 아래와 같은 답변을 받았다.

실제로 script를 맨 아래에 배치해 두었고 간단한 HTML, CSS였기에 이렇게 나타나지 않았나 싶다.
참고
중요 렌더링 경로 - 웹 성능 | MDN
중요 렌더링 경로 (Critical Rendering Path)는 브라우저가 HTML, CSS, Javascript를 화면에 픽셀로 변화하는 일련의 단계를 말하며 이를 최적화하는 것은 렌더링 성능을 향상시킵니다. 중요 렌더링 경로는 Do
developer.mozilla.org
주요 렌더링 경로 성능 분석 | Articles | web.dev
주요 렌더링 경로 성능 병목 현상을 식별하고 해결하는 방법을 알아보세요.
web.dev
'개발' 카테고리의 다른 글
2. 프레임워크가 렌더링에 주는 이점과 React Batching (0) | 2025.03.16 |
---|---|
입력 값이 바뀜에 따라 요청이 계속 보내진다면? (Throttling & Debouncing) (4) | 2025.01.12 |
"NET::ERR_CERT_DATE_INVALID" 에러 & SSL 인증서 재발급 (0) | 2024.09.13 |
내가 생각하는 프로젝트 규모에 따른 프론트 기술스택 선정기준 (0) | 2024.08.24 |
[Webflow] Scroll into view 애니메이션이 한 번 밖에 실행이 안될때 (0) | 2024.07.13 |