웹 페이지는 HTML을 단순히 화면에 출력하는 것이 아니라, 브라우저의 렌더링 파이프라인(Rendering Pipeline) 을 거쳐 화면에 그려집니다.
이 과정에서 성능에 큰 영향을 미치는 개념이 바로 Reflow와 Repaint입니다.
이 두 개념을 정확히 이해하면 프론트엔드 성능 최적화의 방향이 명확해집니다.

브라우저는 다음과 같은 과정을 통해 화면을 렌더링합니다.
Reflow와 Repaint는 이 중 Layout과 Paint 단계에 해당하며, 빈번하게 발생할 경우 성능 저하의 원인이 됩니다.
Reflow(Layout) 는 브라우저가 요소의 위치와 크기를 다시 계산하는 과정을 의미합니다.
DOM 구조가 변경되거나, 레이아웃에 영향을 주는 CSS 속성이 변경되면 발생합니다.
width, height, margin, padding 변경display, flex 등font-size , font-weight 등position,top,left 등const el = document.querySelector('.box');
el.style.width = '200px'; // Reflow 발생
Reflow는 해당 요소뿐 아니라 부모와 자식 요소까지 연쇄적으로 영향을 줄 수 있어 비용이 매우 큰 작업입니다
(CPU를 사용)
Repaint(Paint) 는 요소의 레이아웃은 그대로 두고 시각적인 스타일만 다시 그리는 과정)입니다.
color, background-color 변경border-color , border-radius 변경const el = document.querySelector('.box');
el.style.backgroundColor = 'red'; // Repaint 발생
Repaint는 Reflow보다 비용이 적지만, 자주 발생하면 성능에 영향을 줄 수 있습니다.
(GPU를 사용)
레이아웃에 영향을 주는 속성은 가능한 한 초기 렌더링 시에만 설정하고,
동적 변경은 최소화하는 것이 좋습니다.
❗reflow 유발 대표 속성
width, height
margin, padding
border,
top, left, right, bottom
// ❌ 반복적인 Reflow
for (let i = 0; i < 100; i++) {
el.style.width = `${i}px`;
}
레이아웃 정보를 읽는 순간, 브라우저는 강제로 최신 레이아웃 계산(Reflow) 을 수행합니다.
// ❌ Layout Thrashing
el.style.width = '200px';
console.log(el.offsetWidth); // 강제 Reflow
// ✅ 읽기와 쓰기 분리
const width = el.offsetWidth;
el.style.width = width + 10 + 'px';
transform과 opacity는 Reflow를 발생시키지 않고 Composite 단계에서 처리됩니다.
GPU 가속을 사용할 수 있어 성능상 가장 유리합니다.
/* ❌ */
.box {
left: 100px;
}
/* ✅ */
.box {
transform: translateX(100px);
}
will-change는 브라우저에 앞으로 변경될 속성을 미리 알려주는 힌트입니다.
.box {
will-change: transform;
}
❗주의사항
과도한 사용은 메모리 낭비가 발생하므로 필요한 요소에만 적용해야 합니다!
애니메이션 시작 직전에만 적용하고 종료 후 제거 권장
display: none : 레이아웃에서 제거 → Reflow 발생visibility: hidden: 공간 유지 → Repaint만 발생상황에 맞게 선택하는 것이 중요합니다.
transform, opacity 중심으로 설계