노트

리플로우(레이아웃 재계산)

Reflow

프런트엔드#browser#performance · 연결된 개념 13개

쉽게 말하면

리플로우는 가구 하나의 크기를 바꾸면 방 안 다른 가구 자리까지 다시 재고 배치하는 일이에요. 요소의 크기나 위치가 바뀌면 브라우저가 레이아웃을 다시 계산하고 다시 칠하기까지 해서 비싼 단계예요.

비유가 깨지는 곳 숨기는 방법에 따라 비용이 달라요. display: none은 자리가 사라져 리플로우가 나지만, visibility: hidden은 리페인트만 일어나고 opacity: 0은 합성 단계에서 처리될 수 있어요.

요소의 크기나 위치가 바뀌어 브라우저가 레이아웃을 다시 계산하는 일. 렌더링 파이프라인에서 대개 가장 비싼 단계이고, 리플로우가 일어나면 뒤따라 페인트와 합성도 다시 한다.

언제 일어나나

  • DOM 노드를 추가·삭제·이동할 때, display를 none과 다른 값 사이에서 바꿀 때
  • 기하에 영향을 주는 속성을 바꿀 때: width·height, margin·padding·border 두께, top·left, font-size·line-height, flex·grid 관련 속성 등
  • 창 크기가 바뀔 때, 웹폰트나 이미지가 늦게 로드되어 크기가 정해질 때(이미지 크기를 비워 두면 CLS(Cumulative Layout Shift)도 나빠진다)
  • 레이아웃 값을 읽을 때(offsetWidth, getBoundingClientRect 등). 미뤄 둔 변경을 즉시 반영해야 해서 강제로 일어난다 → 레이아웃 스래싱

바뀐 요소 하나로 끝나지 않고 부모·형제·자식까지 번질 수 있다. 최악이면 문서 전체를 다시 계산한다.

숨기는 방법에 따라 비용이 다르다

방법레이아웃 자리바꿀 때
display: none사라진다(트리에서 빠짐)주변 배치가 바뀌어 리플로우
visibility: hidden그대로 남는다기하가 그대로라 리페인트만
opacity: 0그대로 남는다합성 단계에서 처리할 수 있다

visibility: hidden과 opacity: 0은 보이지 않을 뿐 자리를 차지하고, opacity: 0인 요소는 여전히 클릭된다. 자주 켜고 끄는 요소는 자리를 비워 둬도 되는지에 따라 고른다.

줄이는 법

  • 스타일을 하나씩 바꾸지 말고 클래스를 바꿔 한 번에 적용한다
  • 노드를 여러 개 넣을 때는 DocumentFragment에 모아 한 번에 붙인다
  • 레이아웃 값은 반복문 밖에서 한 번 읽어 변수에 담는다
  • 움직이는 요소는 top·left 대신 transform을 쓴다 → 합성 단계와 transform·opacity
  • 크기가 바뀌는 요소를 position: absolute·fixed로 문서 흐름에서 빼 두면, 그 요소가 바뀌어도 형제 요소의 배치는 다시 계산하지 않아도 된다
  • 불필요하게 깊은 DOM을 줄인다. 한 단계의 변경이 위로는 루트까지, 아래로는 바뀐 노드의 자식까지 번질 수 있다
  • 화면 밖 영역은 content-visibility로 레이아웃 자체를 건너뛰게 할 수 있다
// 나쁨: 읽기마다 강제 리플로우
for (const el of items) el.style.height = box.offsetHeight + 10 + 'px'
 
// 좋음: 한 번 읽고 쓰기만 반복
const h = box.offsetHeight
for (const el of items) el.style.height = h + 10 + 'px'

출처: MDN — visibility · MDN — display: none · web.dev — Avoid large, complex layouts and layout thrashing · Google — Minimizing browser reflow

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • Activity와 숨겨진 라우트 보존

    Activity는 React 19.2의 컴포넌트로, UI를 언마운트하지 않고 display: none으로 숨기면서 state와 DOM(Document Object Model)을 보존한다. 숨기는 동안 Effect는 정리(cleanup)된다. 예전 이름은 Offscreen이다.

  • 반응형 웹 디자인

    하나의 페이지가 화면 크기와 기기에 맞춰 레이아웃·이미지·글자 크기를 바꾸도록 만드는 접근. 미디어 쿼리(Media Query), 유연한 레이아웃(Flexible Layout), 반응형 미디어(Responsive Media)가 세 축이다.

  • 구성요소 줄이기

    셀 수 있는 모든 구성요소(파일, 폴더 깊이, 클래스, 함수, 분기, 변수, 테이블, 필드, 테스트 케이스…)는 비용이라는 관점. 심플 디자인의 네 번째 규칙을 실무 기준으로 풀어낸 것이다.

  • Tailwind CSS

    flex, px-4, text-sm처럼 속성 하나를 담은 유틸리티 클래스(Utility Class)를 마크업에 조합해 스타일을 입히는 CSS 프레임워크. 빌드할 때 소스를 훑어 실제로 쓰인 클래스의 CSS만 만들어 내는 빌드 도구이고, 런타임에 돌아가는 JS(JavaScript)는 없다.

  • Flexbox와 Grid 비교

    flexbox는 한 방향으로 흐르는 1차원 배치, css-grid는 행과 열을 함께 다루는 2차원 배치다. 크기를 누가 정하느냐도 다르다. flex는 아이템과 콘텐츠가, grid는 컨테이너의 트랙이 정한다.

보기 옵션