렌더링 최적화

DonghoChoi·2023년 5월 11일
0
post-thumbnail

들어가며

"로딩 속도 1초가 빨라지면 아마존 판매량의 1%, 구글 검색량의 0.2%, 월마트의 전환율이 2%가 증가... 서비스의 사용자 경험에서 성능은 기본적이면서도 매우 중요한 부분을 차지" - 사용자 경험과 성능 개선 방법 in 카카오웹툰

확실히, 웹페이지 로딩이 버벅이면 금새 피곤함을 느껴서 다른 웹사이트로 옮기거나 창을 꺼버릴 것입니다.

이번 포스팅에서는 렌더링 최적화에 대해서 학습한 내용을 정리했습니다.

렌더 블로킹

페이지 렌더링을 정지시키는 리소스가 있습니다. 대표적인 것들은 아래와 같습니다.

  • CSS: 브라우저에서는 DOM과 CSSOM을 모두 사용할 수 있게 될 때까지 렌더링을 차단하므로, 최초 렌더링에 걸리는 시간을 최적화하려면 필요하지 않은 CSS는 초기 렌더링에서 보류하고, 필요한 CSS는 최대한 빠르게 다운로드 되어야 함.

HTML 파싱은 한 줄 한 줄 차례대로 진행되므로, 문서 상단의 meta태그에 link태그를 작성해야 함.

또한 초기 렌더링 리소스에 해당하지 않는 CSS는 media어트리뷰트에 미디어 쿼리를 사용하여 비차단 요소로 분류되도록 명시함.

  • JavaScript: DOM 파싱을 진행하다가 script태그를 만나면 자바스크립트 엔진이 스크립트 실행을 모두 마칠 때까지 DOM 파싱을 중단하므로, 스크립트 실행을 우선해야할 상황이 아니라면 DOM 파싱이 모두 완료된 이후에 script태그를 만나도록 해야함.

script태그를 body태그 하단에 작성.
(webpack 등의 번들러 플러그인이 빌드된 스크립트를 body태그 하단에서 불러오도록 HTML을 후처리하는 이유)

만일 src어트리뷰트로 스크립트를 로드하며 동시에 DOM 파싱이 중단되지 않고 병렬 처리되길 원한다면, asyncdefer어트리뷰트를 사용함.

  • asyncdefer의 공통점: DOM 파싱을 중단하지 않고 외부 스크립트를 비동기적으로 로드.
  • 차이점: 스크립트의 실행 시기. (async: 스크립트 로드가 완료된 직후, DOM 생성을 중단 후 실행. defer: DOM 생성이 완료되면 실행.)
  • CSSOM은 Script Blocking 요소: CSSOM 생성이 신속히 이루어져야 스크립트 실행도 빠르게 이어지므로, 렌더링 최적화 관점에서 CSS 리소스는 중요한 요소이다.

리렌더링

리렌더링 자체를 안할 수는 없을 것입니다. 렌더링 과정에서나 혹은 사용자 인터렉션에 따라서 현재 페이지에서 렌더 요소를 변경시켜야 하는 일이 흔하게 벌어지기 때문입니다.

JavaScript에서 DOM API를 통하여 DOM 요소나 CSSOM 요소를 조작하면 렌더 트리가 재합성되어 리렌더링이 이루어집니다.

CRP 리렌더링 과정 중 컴퓨팅 파워를 많이 소모하는 단계를 순위로 매기면, 1위는 리플로우, 2위는 리페인트, 3위는 컴포지션입니다. 특히 컴포지션은 CPU를 사용하는 다른 두 단계와 달리 GPU를 사용하기 때문에 CPU와 GPU의 병렬 작업으로 성능상 이점이 있습니다.

염두에 두어야 할 점은, 리렌더링 과정에서 세 단계를 반드시 모두 거치지는 않는다는 것입니다. 갱신이 필요한 단계만 거치게 됩니다.

따라서 각 단계를 일으키는 요인을 파악한다면, 성능에 악영향을 끼치는 작업을 자제하거나, 동일한 기능을 구현하되 성능 하락을 방지할 수도 있습니다.

  1. 리플로우와 리페인트를 최소한으로 발생시킴.
  2. 같은 기능을 한다면 컴포지션으로 대체함.
  3. 레이어를 잘 분리하고 최적의 레이어를 구성함.

리플로우가 일어나는 대표적인 속성: position, width, height, left, top, right, bottom, margin, padding, border, border-width, clear, display, float, font-family, font-size, font-weight, line-height, min-height, overflow, text-align, vertical-align, white-space

리페인트만 일어나는 대표적인 속성: background, background-image, background-position, background-repeat, background-size, border-radius, border-style, box-shadow, color, line-style, outline, outline-color, outline-style, outline-width, text-decoration, visibility

위의 2번의 대표적인 예가 position vs transform입니다.transform을 사용한다면 GPU를 사용하는 컴포지션만 발생시키므로 끊김없는 애니메이션을 구현할 수 있습니다.

마치서

기능 구현에만 몰두하다보면 렌더링 최적화에 대한 고민을 생략하는 실수를 하게 되는데요. 더 나은 개발자가 되려면 넓은 시각을 갖고 환경적인 측면을 고려하며 작업해야 함을 되새기는 계기가 되었습니다.

다음 포스팅에서는 CRP 밖에서의 관점으로도 최적화를 이룰 수 있는 방법이 있는지에 대해 학습하여 정리해보겠습니다.

참고한 곳
https://velog.io/@soorokim/Render-Blocking
https://datalater.github.io/posts/browser-rendering

profile
공부만일 살 길

0개의 댓글