브라우저 렌더링이란?
클라이언트에서 서버가 응답한 HTML을 화면에 그려내기 위한 일련의 과정입니다.
핵심 포인트
- 렌더링 엔진이 수행하는 작업입니다
- 메인 스레드를 사용하기 때문에 해당 작업이 진행되는 동안 사용자 작업이 블로킹됩니다
렌더링 엔진
브라우저마다 서로 다른 렌더링 엔진을 사용합니다.
Webkit (Safari, 구 Chrome)

Gecko (Firefox)

두 엔진 모두 기본적인 렌더링 흐름은 유사하며, Parsing → Attachment → Layout → Paint 단계를 거칩니다.
렌더링 과정
1. Parsing (파싱)
HTML과 CSS 리소스를 파싱하여 DOM, CSSOM 트리를 생성합니다.
렌더링 엔진이 이해할 수 있는 구조로 변환하는 단계이며, 작업 도중 CSS, JS 요청이 발생할 수 있습니다.
- HTML 문서의 계층적인 구조를 트리 자료구조를 사용해 표현
- 각 노드에 접근하여 속성과 메소드를 이용할 수 있는 API 제공
2. Attachment (결합)
DOM과 스타일 규칙을 결합하여 Render Tree를 생성합니다.
Render Tree란? 실제 화면에 표현될 노드로 구성된 트리입니다.
Render Tree에 포함되지 않는 요소:
display: none스타일이 적용된 노드<meta>,<script>등의 비시각적 노드
3. Layout (Reflow)
Render Tree의 루트부터 시작해, 화면상에서 보일 요소의 너비, 높이, 위치 등을 계산합니다.
모든 상대적인 값들은 절대단위인 px로 변환됩니다.
4. Paint
계산된 레이아웃 정보를 기반으로 화면에 그려냅니다.
Reflow와 Repaint
다음과 같은 경우 반복된 레이아웃 계산(Reflow)과 페인팅(Repaint)이 실행됩니다.
DOM 요소 추가 또는 삭제
const $div = document.querySelector('li');
const $item = document.createElement('item');
$div.appendChild($item);
브라우저 창 리사이징
뷰포트 크기 변경에 따라 레이아웃이 재계산됩니다.
레이아웃 변경 스타일 적용
const $div = document.querySelector('li');
$div.style.height = '100px';
elem.offsetTop,elem.offsetHeightelem.getBoundingClientRect()elem.scrollBy(),elem.scrollTo()elem.focus()window.scrollX,window.scrollY
작업의 종류에 따라 Reflow → Repaint가 순차 발생할 수 있고, Reflow가 불필요한 작업(예: 배경색상 변경)은 Repaint만 발생합니다.
최적화 방법
DOM 업데이트 일괄처리
documentFragment에 임시로 트리를 만들어서 한 번에 붙이는 방식입니다.
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
fragment.appendChild(li);
}
document.querySelector('ul').appendChild(fragment);
Virtual DOM
변경 여부를 비교하고, 실제 변경이 일어난 노드에만 변경을 적용합니다.
React의 Virtual DOM - React는 Virtual DOM을 활용하여 실제 DOM 조작을 최소화하고, 배치 업데이트를 통해 성능을 최적화합니다.
계산된 스타일 재사용
레이아웃을 유발하는 속성 접근을 최소화하고, 필요한 경우 값을 캐싱하여 재사용합니다.
