브라우저 렌더링 과정과 CSS를 통한 최적화하는 방법에 대한 기록입니다.
💡 Overview
브라우저 렌더링은 위와 같은 과정으로 이루어집니다.
DOM 요소의 스타일 속성이 변경될 경우 위 과정이 다시 발생하게 됩니다.
하지만, 스타일 속성마다 발생시키는 과정의 차이가 있습니다.
과정은 Reflow와 Repaint 그리고 Composition-Only 세 가지로 분류됩니다.
Reflow > Repaint > Composition-Only순으로 연산 비용이 많습니다.
💡 Reflow [ 리플로우 ]
리플로우는 최초 렌더링 과정 발생 이후, 요소의 위치나 크기가 변경될 때 발생하는 연산입니다.
( 윈도우 리사이징 element 위치 및 크기 변경 폰트의 변화 등 )
연산 비용이 큰 작업이므로 개선할 수 있는지 고려가 필요합니다.
💡 Repaint [ 리페인트 ]
리페인트는 최초 렌더링 과정 발생 이후, 요소의 외형이 변경되지만 레이아웃에 영향을 주지 않는 스타일 변경이 생길 때 발생하는 연산입니다.
( 색상 테두리 색상 테두리 그림자 등 시각적인 요소 )
리페인트 과정은 레이아웃 과정을 생략합니다.
💡 Composition-Only [ 합성 ]
합성 과정은 레이아웃, 페인트 과정을 생략합니다.
대표적인 스타일 속성으로는 transform opacity will-change 있습니다.
레이아웃, 페인트 과정을 생략하기 때문에 연산 비용이 가장 적습니다.
💡 right와 transform 비교
사이드바 애니메이션에 right 속성과 transform 속성을 한 번씩 적용하여 두 속성을 비교해 보겠습니다.
( 현재 저의 블로그는 768px를 기준으로 헤더에 사이드바 조건부 렌더링 됩니다. )
right와 transform 속성을 비교하는 이유는 두 속성 모두 사이드바의 애니메이션 동작을 구현할 수 있기 때문입니다.
외관상 같은 동작이지만 내부적으로 렌더링 과정에서 어떤 차이가 있는지 확인할 수 있습니다.
5초간 사이드바의 애니메이션을 지속적으로 동작시키고 렌더링 과정을 비교했습니다.
1️⃣ right 속성 [ Reflow 발생 ]
Performance 탭에서 성능 기록을 5초간 진행했습니다.
가장 빈도가 높은 작업을 Call Tree 탭을 통해 확인했습니다.
right 속성은 리플로우 과정을 발생시킵니다.
Style - Layout - Pre Paint - Paint - Layerize - Commit 메인 스레드에서의 모든 과정을 연산하는 것을 확인할 수 있습니다.
2️⃣ transform 속성 [ Composition-Only 발생 ]
transition transform 속성은 대표적으로 grpahic layer 로 승격시켜주는 속성입니다.
Call Tree 결과에서 확인할 수 있듯 레이아웃과 페인트 과정이 생략되어 메인 스레드에서의 연산이 빠릅니다.
3️⃣ right, transform 비교
Paint : 39.1ms -> 생략
Layout : 26.3ms -> 생략
Pre Paint : 89.2ms -> 8.7ms
Layerize : 40.0ms -> 0.9ms
transform 속성은 Layout, Paint 과정을 생략하고 Commit으로 넘어가는 것을 확인할 수 있습니다.
💡 마무리
right와 transform 속성을 통해 Reflow와 Composition-Only 과정을 비교할 수 있었고,
Composition-Only 과정은 메인 스레드 연산을 빠르게 처리하는 것을 직접 확인할 수 있었습니다.
60fps는 1초에 60장의 프레임이 그려지고 1장의 프레임이 16.6ms 시간 안에 그려져야합니다.
이를 달성하지 못하면 버벅거리는 현상(jank)이 발생합니다.
무거운 연산이 더해진 드래그 또는 스크롤 이벤트를 원인으로 버벅거림이 발생하는 곳에, 스타일 속성을 이용한 최적화를 적용한다면 효과적인 해결책이 될 수 있을 것 같습니다.
🔦 References
Written by
At
Mon Jan 22 2024