2020. 11. 9. 21:17ㆍ웹 프론트엔드 깊게 이해하기/성능 최적화
(리)레이아웃과 리페인트 그리고 리컴포짓
(참조 : https://developers.google.com/web/fundamentals/performance/rendering/?hl=ko)
일단 브라우저가 HTML을 한번 다 읽고 나서 파싱까지 모두 끝냈다면 DOM 과 CSSOM 트리를 처음부터 다시 만드는 작업은 일어나지 않습니다. 하지만 자바스크립트나 CSS(transition, animation 등)에 의해 DOM 트리나 CSSOM 트리가 변경되면 렌더 트리는 처음부터 끝까지 다시 만들어지고, 그 후의 모든 과정이 다시 수행됩니다. 스타일 과정을 포함한 모든 과정을 다 수행하는 것을 레이아웃, 혹은 리플로우라고 부릅니다.
그렇다면 이러한 리플로우 과정은 '어느 DOM 요소의 기하학적 속성을 변경하느냐' 혹은 '어느 DOM 요소 자체를 삭제하거나 추가하느냐'에 따라 처리 시간이 달라질 수 있을까요? 정답은 No 입니다. 어떻게 보면 비합리적이라고 느낄 수도 있지만, 리플로우는 어디서 어떤 식으로 트리거되든 전체 요소에 대한 계산을 처음부터 다 다시합니다.
(참조 : https://developers.google.com/web/fundamentals/performance/rendering/?hl=ko)
하지만 '반드시' 그런것은 또 아닙니다. 중요한 것은 해당 자바스크립트 코드로 인한 변경사항이 '레이아웃 작업을 다시 수행할 필요가 있는지' 즉, 전체 요소의 높이, 넓이, 위치에 영향을 줄 수 있느냐는 것입니다. 만일 아무 영향이 없다면 레이아웃 과정은 굳이 거칠 필요가 없이 스타일, 페인트와 합성 & 렌더 과정만 거쳐주면 될 것입니다. 이것을 '리페인트'라고 부릅니다. 겨우 한 단계 건너 뛰는 것 같겠지만 레이아웃 과정은 정말로 무거운 작업이기 때문에 이는 사실 엄청난 차이를 만듭니다.
자바스크립트를 통해 DOM 트리의 내용을 바꾸면 거의 무조건 화면의 기하학적인 변화가 생길 것이기 때문에 렌더 트리는 재생성되어야 할 것입니다. 하지만 CSS 속성은 요소에 기하학적인 영향을 주지 않는 것이라면 렌더 트리의 내용이 그저 수정되고 끝납니다.
그리고 마지막으로, 스타일 과정은 트리거되지만 레이아웃과 페인트 과정을 건너뛰고 오직 합성 과정만을 거치는 '리컴포짓'이 있습니다. 이는 레이어의 순서를 뒤바꾸거나 레이어 자체를 조작하는 작업을 생각해볼 수 있습니다. 이 리컴포짓을 최대한 활용하는 것이 브라우저의 연산을 최소화할 수 있고 성능을 최적화할 수 있는 비결이라고 할 수 있습니다. 이 리컴포짓을 일으키는 대표적인 CSS 속성으로는 transform 을 들 수 있습니다.
*자바스크립트는 그렇다 쳐도 CSS 가 무조건 style 과정을 트리거하는 것은 또 아닙니다. 예를 들어 flexbox 관련 CSS 속성의 경우, 반응형 처리가 되는 것을 봐서 레이아웃, 페인트, 컴포짓 과정 모두 일어나는 것을 알 수 있지만 CSSOM 이나 DOM 자체에는 변경이 전혀 없기에 렌더 트리를 다시 구성하는 style 과정은 일어나지 않습니다.
그렇다면 좋은 리렌더링 성능을 위해서는 되도록 레이아웃을 발생시키지 않는 CSS 속성의 변화를 주로 사용하는 것이 좋다는 결론이 나옵니다. CSS 속성마다 어떤 단계부터 다시 수행하게 되는지는 다음의 링크에 잘 정리되어 있습니다.
CSS properties by style operation required - Google Drive
'웹 프론트엔드 깊게 이해하기 > 성능 최적화' 카테고리의 다른 글
스타일과 레이아웃 과정 최적화 (0) | 2020.11.17 |
---|---|
자바스크립트를 활용한 인터랙션 성능 최적화 (0) | 2020.11.17 |
웹 성능 최적화의 척도(RAIL) (0) | 2020.11.16 |
웹 프론트엔드 성능 최적화(1) - 초기 렌더링 과정의 이해 (0) | 2020.11.04 |
크롬 개발자 도구를 사용한 성능 측정 (0) | 2020.10.22 |