Skip to content

브라우저 렌더링 성능과 Reflow · Repaint

앞선 글에서 봤듯, <script>에 의해 렌더링이 차단되면 브라우저가 화면을 그리는 시점도 지연된다. 이제 실제로 화면을 다시 그릴 때(Reflow·Repaint) 어떤 일이 일어나는지 살펴보자 👀 !

1. 렌더링이란?

렌더링(Rendering)은 브라우저가 HTML, CSS, JavaScript를 해석하여 실제 픽셀 단위의 화면으로 그려내는 과정을 말한다. 렌더링은 단순히 DOM과 CSSOM을 만드는 데서 끝나지 않는다.
이 두 모델을 결합해 Render Tree → Layout → Paint → Composite의 단계를 거친다.

💡 DOM/BOM/CSSOM이 데이터 구조라면, 렌더링은 그것을 화면에 시각화하는 프로세스다.


2. 렌더링 과정 요약

(HTML → DOM → CSS → CSSOM →) DOM + CSSOM → Render Tree → Layout → Paint → Composite

단계설명핵심 포인트
DOM 생성HTML을 파싱해 노드 트리 생성HTML 구조 인식
CSSOM 생성CSS 규칙을 파싱해 스타일 트리 생성스타일 계산
Render Tree 생성DOM + CSSOM 결합실제 그릴 요소만 포함
Layout (Reflow)각 요소의 위치, 크기 계산브라우저가 좌표를 계산
Paint (Repaint)계산된 스타일·색상 등을 화면에 픽셀로 그림시각화 단계
Composite여러 레이어를 합성해 최종 화면 완성GPU 가속 등 사용

3. Reflow와 Repaint란?

렌더링 이후에도 JS나 CSS에 의해 DOM이 변경되면 브라우저는 변경된 부분을 다시 계산해야 한다. 이때 발생하는 게 바로 Reflow와 Repaint다.

구분설명발생 조건비용
Reflow (Layout)레이아웃(위치·크기)을 다시 계산DOM 구조, 크기, 위치 변경 시높음
Repaint (Paint)요소의 스타일(색상 등)을 다시 그림색상, 배경만 변경 시중간

예를 들어, 버튼의 크기를 JS로 바꾸면 Reflow + Repaint가 일어나고, 버튼 색상만 바꾸면 Repaint만 발생한다.

plaintext
Reflow (Layout 다시 계산) → Repaint (다시 그리기) → Composite (합성)

💡 Reflow는 Repaint를 반드시 유발하지만, Repaint는 Reflow 없이도 발생할 수 있다.


4. Reflow를 유발하는 대표적인 동작

렌더링 성능을 떨어뜨리는 대부분의 원인은 불필요한 Reflow에 있다. 다음은 대표적인 Reflow 트리거(유발 요인)들이다.

원인예시 코드비고
DOM 구조 변경element.appendChild()새 노드 추가 시 전체 레이아웃 재계산
스타일 변경element.style.width = "100px"위치·크기 변경 시 Reflow 발생
요소 크기 측정offsetWidth, clientHeight, getComputedStyle()강제 Reflow(triggered layout)
클래스 토글 반복element.classList.toggle("active")CSS 전환 효과 시 빈번히 발생
윈도우 리사이즈window.resize전체 Layout 재계산

5. 성능 최적화 전략

Reflow/Repaint는 완전히 피할 수 없지만, 최소화할 수는 있다. 자주 쓰이는 최적화 방법에 대해 알아보자!

5-1. DOM 접근 최소화 (읽기/쓰기 횟수 줄이기)

DOM에 접근할 때마다 브라우저는 Layout 계산을 확인해야 하므로, DOM 접근은 모아서 한 번에 수행한다.

js
// 나쁜 예시 (Reflow 3번)
box.style.width = "100px";
box.style.height = "100px";
box.style.margin = "10px";

// 좋은 예시 (한 번에 적용)
box.style.cssText = "width:100px; height:100px; margin:10px;";

5-2. Layout Thrashing 피하기 (읽기-쓰기 분리)

DOM을 읽고(offsetWidth) 바로 다시 쓰는(style) 동작을 반복하면 브라우저가 매번 레이아웃을 다시 계산해야 한다.

js
// 나쁜 예시
div.style.width = div.offsetWidth + 10 + "px"; // 읽기 → 쓰기 → 읽기...

// 좋은 예시
const width = div.offsetWidth;
div.style.width = width + 10 + "px";

5-3. 클래스 변경 시 CSS 전환 최소화

애니메이션이나 hover 효과처럼 잦은 스타일 변경은 transform, opacity 속성을 활용해 Reflow 없이 GPU 레벨에서 처리하도록 유도한다.

css
/* width, height, top, left 등은 Reflow 발생 */
.bad {
  width: 100px;
  left: 50px;
}

/* transform과 opacity는 GPU 합성 단계에서 처리 (Repaint만 발생) */
.good {
  transform: translateX(50px);
  opacity: 0.8;
}

5-4. visibility vs display

display: none은 요소를 제거하므로 Reflow 발생
visibility: hidden 은 공간을 유지하므로 Repaint만 발생
opacity: 0 은 투명하게만 만들어 GPU 합성으로 처리

속성화면 표시공간 유지비용
display: noneXXReflow
visibility: hiddenXORepaint
opacity: 0X (투명)OGPU 합성

5-5. 애니메이션은 GPU-friendly 속성으로

  • 가능하면 transform, opacity를 사용
  • CSS will-change 속성으로 브라우저에게 앞으로 바뀔 속성을 미리 알려 최적화 유도
css
.card {
  will-change: transform, opacity;
  transition: transform 0.3s ease;
}

6. Reflow/Repaint가 심한 코드 예시

js
// bad: 각 반복마다 DOM 접근 + 스타일 변경 (매번 Reflow)
// 각 appendChild마다 Reflow 발생 → 100번 반복
for (let i = 0; i < 100; i++) {
  const el = document.createElement("div");
  el.textContent = i;
  document.body.appendChild(el); // 매번 Reflow 유발
}

// good: DocumentFragment로 묶어서 한 번에 추가 (Reflow 1번)
const frag = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const el = document.createElement("div");
  el.textContent = i;
  frag.appendChild(el); // 메모리상에서만 작업
}
document.body.appendChild(frag); // 단 한 번의 Reflow

7. 렌더링 최적화의 핵심 요약

구분설명권장 방법
ReflowLayout 다시 계산 (무거움)DOM 변경 최소화, transform 사용
Repaint다시 그리기 (중간 비용)색상/투명도 변경 중심으로 처리
Layout Thrashing읽기-쓰기 반복으로 Reflow 폭증읽기와 쓰기 분리
Batching스타일 변경 모아서 한 번에 적용cssText, classList 활용
GPU 활용transform, opacity, will-change애니메이션 최적화

💡 결국 자바스크립트 로딩 최적화(defer)는 단순한 다운로드 전략이 아니라,

브라우저의 렌더링 파이프라인 전체(Reflow·Repaint 포함)를 가볍게 만드는 출발점이다.

💡 요약

  • Reflow = Layout 재계산, Repaint = 다시 그리기
  • 둘 다 과도하면 렌더링이 느려진다.
  • DOM 접근, 스타일 변경은 최대한 모아서 수행하라.
  • transform / opacity 기반 애니메이션이 가장 성능 친화적이다.
  • 궁극적으로 “렌더링 차단 최소화 → Reflow 최소화 → Repaint 최소화”가 브라우저 성능의 핵심이다.