본문 바로가기
CS 질문

[Deep Dive CS - Q28] Rendering

by 민챙이_99 2025. 12. 22.

Q28. 모바일 웹에서 메뉴 슬라이드 애니메이션을 구현했는데 버벅거림(Jank)이 발생했습니다. left 속성을 사용한 것을 확인하고 transform: translate로 변경하여 해결했습니다. 왜 left는 느리고 transform은 빠를까요? 브라우저의 '스레드(Thread)'와 '파이프라인' 관점에서 설명해 주세요.

 

네, 가장 큰 차이는 렌더링 파이프라인의 단계실행되는 스레드가 다르기 때문입니다.

 

첫째, 파이프라인 관점입니다. left 속성은 요소의 기하학적 위치를 변경하므로 Layout(Reflow) → Paint → Composite의 모든 단계를 거쳐야 합니다. 반면, transform은 Layout과 Paint 과정을 건너뛰고 Composite(합성) 단계만 수행하기 때문에 비용이 훨씬 저렴합니다.

 

둘째, 스레드 관점입니다. left 애니메이션은 Main Thread에서 실행됩니다. Main Thread는 자바스크립트 실행, DOM 조작 등 처리할 작업이 많기 때문에, JS 연산이 조금이라도 무거워지면 애니메이션 프레임이 드랍되는 Jank(버벅거림) 현상이 발생합니다.

 

반면, transform은 해당 요소를 별도의 레이어로 분리하여 Compositor ThreadGPU에게 작업을 위임합니다. 덕분에 Main Thread가 멈추더라도 애니메이션은 독립적으로 부드럽게 동작할 수 있습니다

 

 


Q29. 아래 코드는 성능상 심각한 문제를 가지고 있습니다. 어떤 문제가 발생하며, 브라우저의 '렌더 큐(Render Queue)' 최적화 메커니즘과 연관 지어 설명해 주세요.

const box = document.getElementById('box');
for (let i = 0; i < 100; i++) {
  box.style.width = (box.offsetWidth + 1) + 'px';
}

 

브라우저는 원래 렌더링 성능 최적화를 위해 'Render Queue' 시스템을 사용합니다. 자바스크립트로 스타일을 변경(Write)하더라도 이를 즉시 반영하지 않고 큐에 쌓아두었다가, 프레임의 끝에서 한 번에 모아서 처리(Batching)하는 '지연 평가(Lazy Evaluation)' 방식을 취합니다.

 

하지만 위 코드처럼 스타일을 변경한 직후에 offsetWidth 같은 기하학적 속성을 조회(Read)하게 되면 문제가 발생합니다. 브라우저는 개발자에게 '정확한 최신 수치'를 반환해야 한다는 정합성을 지키기 위해, 큐에 쌓아둔 변경 사항을 미루지 못하고 그 즉시 강제로 레이아웃을 계산(Flush)해야 합니다.

 

결과적으로 브라우저가 의도한 '일괄 처리 최적화'가 무력화되고, 루프가 도는 횟수(100번)만큼 레이아웃 계산이 불필요하게 반복되어 프레임 드랍이 발생하게 됩니다