강제 동기 레이아웃: DOM에 쓴 뒤 기하 속성 읽기
무슨 일이 일어나는가
보통 레이아웃은 JavaScript가 끝난 후 프레임마다 한 번 일어납니다. 하지만 DOM을 바꾼 직후 레이아웃 속성 — offsetWidth, scrollHeight, getBoundingClientRect(), getComputedStyle() — 을 읽으면, 답이 보류 중인 변경에 의존하므로 브라우저는 그 자리에서 동기적으로, 작업 안에서 레이아웃을 계산해야 합니다.
강제 레이아웃 한 번은 작은 페이지에서는 저렴합니다. 큰 DOM이거나 루프에서 반복되면(레이아웃 스래싱이 됨) 핸들러에 수백 ms를 더합니다.
알아보는 법
- INP 분해에서 processing time이 길고, DevTools Performance에서 Layout 블록이 스크립트 작업 안에 중첩됨(“Forced reflow” 경고).
- Long Animation Frames API가 스크립트에 큰 forcedStyleAndLayoutDuration을 보고함.
- 핸들러가 DOM 변경과 요소 측정을 동시에 함.
해결 방법
- 작업 안에서 첫 DOM 쓰기 전에 모든 기하 값을 읽으세요.
- 변하지 않는 측정값(요소 크기, 컨테이너 너비)은 이벤트마다 다시 읽지 말고 캐시하세요.
- 변경 후에 반드시 측정해야 한다면, 읽기를 다음 프레임의 requestAnimationFrame으로 미루거나 기하를 폴링하는 대신 ResizeObserver / IntersectionObserver를 사용하세요.
문제
grid.style.width = next + "px" // write: layout is now dirty
const rect = cell.getBoundingClientRect() // read → forced synchronous layout
해결
const rect = cell.getBoundingClientRect() // read first, layout is clean
grid.style.width = next + "px" // write after; browser lays out
// once, before the next paint
사이트 무료로 스캔하기 →