리플로우/리페인트
주디2026.04.08
loading ...
이 주제를 한 문장으로 설명하면?
DOM이나 스타일이 변경될 때 브라우저가 레이아웃을 다시 계산하는 것이 리플로우, 시각적 속성만 다시 그리는 것이 리페인트이며, 리플로우가 훨씬 비싼 작업이다.
관련 키워드 (마인드맵 형태로 나열):
[리플로우 & 리페인트]├── 브라우저 렌더링 파이프라인│ ├── DOM + CSSOM → Render Tree│ ├── Layout (Reflow)│ ├── Paint (Repaint)│ └── Composite├── 리플로우 유발 속성│ ├── width, height, margin, padding│ └── offsetTop, getBoundingClientRect 등 강제 동기 레이아웃├── 리페인트 유발 속성├── color, background-color, box-shadow└── visibility
⚠️ 단순 복붙 금지! 반드시 자신의 말로 재작성할 것
개념 설명 (내 말로):
브라우저가 HTML/CSS를 받아서 화면에 그리기까지의 전체 흐름.
(리플로우/리페인트를 이해하려면 이 파이프라인을 알긴 알아야할 것 같아서 추가했어욥)
동작 원리 / 흐름:
개념 설명 (내 말로):
DOM 요소의 위치, 크기, 구조가 바뀌어서 브라우저가 전체 또는 일부 레이아웃을 다시 계산해야 하는 작업. 변경된 요소뿐만 아니라 그 부모/자식 요소까지 영향을 줄 수 있어 매우 비싸다.
동작 원리 (리플로우를 유발하는 것들) :
브라우저가 아직 계산 안 한 레이아웃을 바로 계산하라고 강제로 시키는 것
원래 브라우저는 최대한 한 번에 처리하려는 경향이 있음
JS 실행 → (모아서) 스타일 계산 → 레이아웃 → 페인트
실제 코드 예시:
// ❌: 읽고 쓰고 읽고 쓰고 → 강제 동기 레이아웃 반복for (let i = 0; i < 100; i++) {const width = el.offsetWidth; // 읽기 → 리플로우 강제 발생el.style.width = width + 1 +
개념 설명 (내 말로):
레이아웃(위치/크기)은 변하지 않고, 시각적 스타일(색상, 배경, 그림자 등)만 바뀌는 경우 발생. 레이아웃 재계산 없이 픽셀만 다시 그리므로 리플로우보다 저렴하지만 여전히 비용이 있다.
동작 원리(리페인트를 유발하는 것들):
실제 코드 예시:
// 리페인트만 발생 (레이아웃 변경 없음)el.style.backgroundColor = 'red'; // 리페인트만el.style.visibility = 'hidden'; // 리페인트만 (공간 유지)// 리플로우 + 리페인트 모두 발생el.style.display = 'none'; // 리플로우 (공간도 사라짐)
이 기술/개념이 왜 이런 방식으로 만들어졌는지 배경을 이해하자
유사한 개념과 차이점 정리 (면접에서 자주 나오는 포인트)
| 구분 | 리플로우 (Reflow) | 리페인트 (Repaint) |
| 비용 | 매우 높음 (주변 요소 연쇄 영향) | 상대적으로 낮음 |
| 주요 원인 | width, height, margin, top | color, background, visibility |
| 필수 여부 | 리플로우 발생 시 리페인트는 무조건 발생 | 리페인트만 단독 발생 가능 |
실제 프로젝트에서 마주칠 수 있는 상황
면접관 앞에서 말하듯이 작성. 읽는 용도가 아니라 말하는 연습을 위한 섹션
[도입 - 핵심 정의 먼저]"리플로우는 DOM 요소의 위치나 크기가 변경되어 레이아웃을 다시 계산하는 작업이고,리페인트는 시각적 속성(색상, 그림자 등)이 변경되어 픽셀을 다시 그리는 작업입니다."[부연 - 왜/어떻게]"브라우저 렌더링 파이프라인은 Layout → Paint → Composite 순서인데,리플로우는 이 전체를 다시 실행시켜 매우 비쌉니다.반면 리페인트는 Paint → Composite만 재실행하고,transform/opacity 변경은 Composite만 건드려 가장 저렴합니다."[마무리 - 실무 연결]"실무에서는 애니메이션에 width 대신 transform을 사용하고,여러 DOM 변경을 DocumentFragment로 일괄 처리해 리플로우 횟수를 줄이는 방식으로 최적화합니다."
면접관이 바쁠 때, 딱 1분 안에 설명하는 버전
리플로우 = 레이아웃 재계산 → 가장 비쌈 (파이프라인 전체 재실행)리페인트 = 픽셀 다시 그리기 → 중간 비용Composite only = transform/opacity → 가장 저렴, GPU 처리최적화 핵심: 리플로우 줄이기 → 읽기/쓰기 분리, transform 사용, 배치 처리
각 질문에 대해 STAR 구조 혹은 두 문장 요약으로 작성
display: none은 레이아웃에서 제거되므로 리플로우를 유발하지만, visibility: hidden은 자리만 차지하고 보이지 않을 뿐이라 리페인트만 유발합니다.
리플로우와 리페인트를 모두 건너뛰고 GPU가 담당하는 합성(Composite) 단계에서만 처리되기 때문입니다.
리플로우는 width, margin 등 레이아웃 관련 속성 변경 시 위치/크기를 재계산하는 것입니다. 리페인트는 color, background 등 시각적 속성만 바뀔 때 픽셀을 다시 그립니다. 리플로우가 훨씬 비싸며, 항상 리페인트도 함께 발생합니다.
스타일 변경(쓰기) 후 레이아웃 정보(offsetWidth 등)를 읽는 순간, 브라우저가 최신 값을 반환하기 위해 계획된 리플로우를 즉시 강제 실행하는 현상입니다. 읽기/쓰기를 분리하거나 requestAnimationFrame을 사용해 방지할 수 있습니다.
A:
const boxes = document.querySelectorAll('.box');boxes.forEach(box => {box.style.width = box.offsetWidth + 10 + 'px'; // 읽고 쓰기 반복}
각 반복마다 offsetWidth(읽기)와 style.width(쓰기)가 교차되어 강제 동기 레이아웃이 N번 발생합니다. 개선: 모든 offsetWidth를 먼저 읽어 배열에 저장한 후, 두 번째 루프에서 style.width를 일괄 설정하면 리플로우가 1~2회로 줄어듭니다.
공부하고 나서 진짜 내 머릿속에 남은 것들만 정리
근데 만약 레이아웃 정보를 읽으려고 하면 아직 스타일 변경 사항이 반영이 되지 않은 시점에, 레이아웃 계산 값을 줘야하는 일이 발생함.
→ 강제 레이아웃 발생!