레이아웃 스래싱(Layout Thrashing, 또는 강제 동기 레이아웃 / 강제 리플로우)은 JavaScript가 DOM 쓰기와 레이아웃 속성 읽기를 반복적으로 번갈아 수행해 브라우저가 페이지 레이아웃을 동기적으로 다시 계산하도록 강제할 때 발생합니다.
레이아웃 무효화(Layout Invalidation) 트리거
이전 DOM 변경으로 레이아웃이 무효화된 상태에서 다음 DOM 속성 및 메서드를 호출하면 계산된 기하 정보의 동기 재계산이 강제됩니다.
요소 속성 및 메서드
박스 기하 정보 및 치수
clientHeight,clientWidthclientLeft,clientTopoffsetHeight,offsetWidthoffsetLeft,offsetTopoffsetParentscrollHeight,scrollWidthscrollLeft,scrollTop
경계 상자(Bounding Box) 조회
getBoundingClientRect()getClientRects()
스크롤 동작
scrollIntoView()scrollIntoViewIfNeeded()scrollByLines()scrollByPages()
텍스트 및 포커스
innerTextouterTextfocus()(포커스 링 및 스크롤 조정을 강제 실행)
마우스 이벤트 속성
MouseEvent 인스턴스의 특정 좌표를 조회하면 일부 브라우저 엔진에서 레이아웃 계산을 유발할 수 있습니다:
layerX,layerYoffsetX,offsetY
Window 메서드 및 속성
window.getComputedStyle()(width, height, margin 또는 transform 같은 레이아웃 종속 값을 조회할 때)window.scrollBy()window.scrollTo()window.scrollX,window.scrollY
Frame, Document 및 이미지
- 레이아웃이 안정화되기 전에 이미지의
width또는height조회 document.body.scrollHeight접근
jQuery 작업
여러 jQuery 헬퍼 메서드는 내부적으로 계산된 레이아웃 값을 읽어옵니다:
// 리플로우(Reflow) 유발
$(elem).offset();
$(elem).offsetParent();
$(elem).position();
$(elem).scrollLeft();
$(elem).scrollTop();
$(elem).css('width'); // 모든 레이아웃 의존 스타일 계산
$(elem).text();
// 기하학적 가시성을 검사하는 가상 선택자
$(':hidden');
$(':visible');
$(':contains');
Layout Thrashing 방지를 위한 모범 사례
1. 읽기 작업과 쓰기 작업 일괄 처리(Batch)
항상 모든 DOM 측정을 먼저 수행한 다음, 모든 DOM 수정을 한꺼번에 처리하세요.
// 나쁜 예: 읽기와 쓰기가 번갈아 일어나 매 반복마다 강제 레이아웃 발생
elements.forEach((el) => {
const width = el.clientWidth; // 읽기 (레이아웃 강제)
el.style.width = width * 2 + 'px'; // 쓰기 (레이아웃 무효화)
});
// 좋은 예: 읽기를 일괄 수행한 뒤 쓰기를 일괄 수행
const widths = elements.map((el) => el.clientWidth); // 일괄 읽기
elements.forEach((el, index) => {
el.style.width = widths[index] * 2 + 'px'; // 일괄 쓰기
});
2. requestAnimationFrame 사용
스타일 변경을 다음 애니메이션 프레임으로 예약하여 브라우저가 렌더링 주기를 최적화하도록 하세요:
const height = element.clientHeight; // 현재 단계에서 읽기
window.requestAnimationFrame(() => {
element.style.height = height + 50 + 'px'; // 다음 프레임에서 쓰기
});
3. CSS Transform 및 Opacity 사용
레이아웃 속성(top, left, width, height) 대신 컴포지터 스레드에서 처리되는 CSS 속성(transform, opacity)을 애니메이션하세요.