Files
2nd/10_Wiki/Topics/성능 최적화(Reflow & Repaint).md
T

5.8 KiB

성능 최적화(Reflow & Repaint)

📌 Brief Summary

Reflow(리플로우)는 요소의 크기나 위치 등 레이아웃이 변경될 때 브라우저가 문서의 구조와 기하학적 형태를 다시 계산하는 과정이며, Repaint(리페인트)는 레이아웃에 영향을 주지 않는 시각적 요소(색상, 배경 등)가 변경될 때 화면에 다시 픽셀을 그리는 과정입니다. 이 두 과정은 브라우저의 렌더링 리소스를 크게 소모하므로 성능 저하와 프레임 드롭의 주요 원인이 됩니다. 유지보수성이 높고 사용자 경험(UX)이 뛰어난 CSS를 설계하기 위해서는 불필요한 리플로우와 리페인트를 최소화하는 렌더링 최적화 전략이 필수적입니다.

📖 Core Content

Reflow와 Repaint의 개념 및 발생 원인

  • Reflow (Layout): 브라우저가 렌더링 과정에서 페이지의 레이아웃을 다시 계산하는 단계입니다. width, height, margin, padding, top, left와 같이 요소의 기하학적 구조를 변경하는 속성이 애니메이션되거나 조작될 때 발생합니다 [1, 2]. 한 요소에서 리플로우가 발생하면 자식 요소, 부모 요소 및 DOM 트리 구조에서 뒤따르는 다른 요소들까지 연쇄적인 리플로우가 유발되므로 성능에 매우 치명적입니다 [3]. 리플로우는 창 크기 조절, 폰트 변경, DOM 노드 조작, 그리고 JavaScript에서 offsetWidthoffsetHeight를 계산하여 레이아웃 정보를 읽어올 때도 유발됩니다 [4].
  • Repaint (Paint): 레이아웃이나 요소의 기하학적 구조에는 영향을 주지 않으면서 color, background-color, visibility, box-shadow, outline 같은 시각적 속성만 변경될 때 발생합니다 [2, 3, 5]. 리플로우보다는 상대적으로 가볍지만, 브라우저가 다른 노드들의 가시성 등을 확인하고 다시 그려야 하므로 여전히 높은 연산 비용이 듭니다 [3, 6].

성능 최적화(Reflow & Repaint 감소) 핵심 기법

  • Compositing(합성) 속성 활용: 애니메이션을 구현할 때는 리플로우와 리페인트를 유발하는 속성 대신 transformopacity를 사용하는 것이 가장 이상적입니다 [6, 7]. 이 속성들은 브라우저의 GPU 가속을 통해 처리(Composite 단계만 수행)되므로 레이아웃 재계산이나 페인팅 과정 없이 부드러운 60fps 애니메이션을 제공합니다 [2, 8].
  • DOM 조작 및 스타일 변경의 일괄 처리(Batching): JavaScript를 통해 개별적으로 여러 개의 인라인 스타일을 설정하면 잦은 리플로우가 발생합니다 [9]. 이를 방지하려면 documentFragment를 활용해 DOM 조작을 일괄 처리하거나, JavaScript로 개별 속성을 변경하는 대신 CSS 클래스를 한 번에 교체하는 방식을 사용해야 합니다 [10, 11].
  • Layout Thrashing(레이아웃 스래싱) 방지: JavaScript 루프 내부에서 DOM의 레이아웃 값(예: offsetWidth)을 읽고 즉시 쓰는 작업을 반복하면, 브라우저가 정확한 값을 반환하기 위해 강제로 동기적인 리플로우를 수행하여 프레임률이 급감합니다 [12, 13]. DOM 읽기와 쓰기 작업을 분리하고, requestAnimationFrame을 사용하여 브라우저의 리페인트 주기에 맞춰 애니메이션을 동기화해야 합니다 [12, 13].
  • DOM 트리 하단부에서의 클래스 변경: 리플로우의 연쇄 작용 스코프를 제한하기 위해, 최상위 래퍼(Wrapper)나 부모 요소 대신 화면 변경에 직접적인 영향을 받는 가장 하위의 DOM 노드에서 클래스를 변경하는 것이 좋습니다 [14].
  • 레이아웃 흐름에서 분리 (position: absolute/fixed): 애니메이션이 적용되는 요소에 position: absolute 또는 fixed를 부여하면 해당 요소가 문서의 정상적인 흐름(Flow)에서 빠지게 됩니다 [9, 15]. 결과적으로 애니메이션 중 주변 요소들의 레이아웃에 영향을 주지 않아 전체 리플로우 대신 해당 요소의 리페인트만 유발하게 됩니다 [15].
  • will-change 속성의 활용: 특정 요소가 곧 애니메이션될 것임을 브라우저에 미리 알려주어 렌더링 최적화를 준비하게 할 수 있습니다 [16, 17]. 이 속성을 사용하면 브라우저가 요소를 최적화할 수 있지만, 성능 문제 발생을 방지하는 최후의 수단으로 써야 하며 과도한 사용은 오히려 성능을 저하시킬 수 있습니다 [16, 18].
  • 테이블 레이아웃 및 복잡한 선택자 회피: 테이블(<table>)은 내용물이나 셀 하나의 크기가 변해도 전체 테이블 노드의 레이아웃을 다시 계산하기 위해 여러 번의 리플로우 패스를 거칠 수 있어 레이아웃 용도로 부적합합니다 [19]. 또한 불필요하게 복잡하거나 깊게 중첩된 CSS 선택자는 브라우저의 파싱 속도를 늦추므로 최대한 직관적이고 단순하게 작성해야 합니다 [11, 20].

🔗 Knowledge Connections

  • Related Topics: CSS 애니메이션(transition / keyframes), CSS 아키텍처 및 렌더링 파이프라인
  • Projects/Contexts: 실무에서 CSS 관리하는 방법, 반응형 디자인 및 고성능 UI 구현
  • Contradictions/Notes: 소스 문헌들은 will-change 속성이 리플로우 및 페인트를 대비한 최적화에 도움을 준다고 소개하면서도, 이를 너무 많은 요소에 남용하거나 미리 예측하여 사용하면 도리어 브라우저 리소스와 메모리를 소모시켜 성능 병목(bottleneck)을 유발할 수 있다고 일관되게 경고합니다 [16-18].

Last updated: 2026-04-26