노트

레이아웃 스래싱

Layout Thrashing

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

쉽게 말하면

레이아웃 스래싱은 가구를 하나 옮길 때마다 방 전체를 줄자로 다시 재는 것과 같아요. DOM을 바꾸고 바로 크기를 읽기를 반복하면, 브라우저가 미뤄 둔 계산을 매번 그 자리에서 해서 느려져요.

비유가 깨지는 곳 브라우저는 원래 계산을 프레임 끝에 몰아서 해요. 그래서 읽기를 먼저 다 하고 쓰기를 나중에 모으면 리플로우가 한 번으로 줄고, 위치 이동은 transform으로 하면 레이아웃을 안 건드려요.

DOM을 바꾸고 곧바로 레이아웃 값을 읽기를 반복해서, 브라우저가 매번 리플로우를 강제로 실행하게 되는 현상. 쓰기 → 읽기 → 쓰기 → 읽기가 반복문 안에서 일어나면 요소 수만큼 레이아웃을 계산한다.

왜 생기나

브라우저는 스타일 변경을 바로 계산하지 않고 "레이아웃이 낡았다"는 표시만 해 둔 뒤 프레임 끝에 한꺼번에 처리한다. 그런데 정확한 기하 값을 요구하는 API를 부르면 미뤄 둔 계산을 그 자리에서 해야 한다.

레이아웃을 강제하는 대표 API: offsetWidth/Height/Top, clientWidth/Height, scrollTop/Height, getBoundingClientRect(), 레이아웃에 의존하는 값을 읽는 getComputedStyle()

// 나쁨: 루프마다 강제 레이아웃
items.forEach(el => {
  el.style.width = '200px'   // 쓰기
  console.log(el.offsetWidth) // 읽기 → 즉시 레이아웃
})
 
// 좋음: 읽기를 모두 끝낸 뒤 쓰기
const widths = [...items].map(el => el.offsetWidth)
items.forEach(el => { el.style.width = '200px' })

피하는 법

60fps(frames per second)라면 한 프레임 예산은 약 16ms인데, DOM이 크면 강제 레이아웃 몇 번으로 금방 넘친다. DevTools Performance 패널에서 보라색 Layout 블록에 "Forced reflow" 경고가 붙으면 이 패턴을 의심하면 된다 → 크롬 개발자 도구 팁

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 반응형 웹 디자인

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

  • Activity와 숨겨진 라우트 보존

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

  • loading 경계와 레이아웃 끌어올리기

    Next.js App Router에서 loading.tsx는 같은 세그먼트의 page와 그 아래(하위 layout 포함)를 suspense로 감싸지만, **같은 세그먼트의 layout은 감싸지 않는다**. 그래서 데이터를 기다릴 필요가 없는 공통 UI(탭바, 필터 헤더)를 page에서 layout으로 끌어올리면 스켈레톤에 덮이지 않고 처음부터 실제 모습으로 보인다.

  • 크로스 브라우징

    크로스 브라우징은 브라우저 종류·버전·기기가 달라도 웹 페이지가 같은 기능을 제공하도록 만드는 일이다. 모든 브라우저에서 픽셀까지 똑같이 보이게 하는 것이 목표가 아니라, 지원하기로 한 환경에서 핵심 기능이 동작하고 오래된 환경에서도 쓸 수는 있게(점진적 향상, Progressive Enhancement) 하는 것이 목표다.

  • Tailwind CSS

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

보기 옵션