"로딩 속도 1초가 빨라지면 아마존 판매량의 1%, 구글 검색량의 0.2%, 월마트의 전환율이 2%가 증가... 서비스의 사용자 경험에서 성능은 기본적이면서도 매우 중요한 부분을 차지" - 사용자 경험과 성능 개선 방법 in 카카오웹툰
확실히, 웹페이지 로딩이 버벅이면 금새 피곤함을 느껴서 다른 웹사이트로 옮기거나 창을 꺼버릴 것입니다.
이번 포스팅에서는 렌더링 최적화에 대해서 학습한 내용을 정리했습니다.
페이지 렌더링을 정지시키는 리소스가 있습니다. 대표적인 것들은 아래와 같습니다.
HTML 파싱은 한 줄 한 줄 차례대로 진행되므로, 문서 상단의
meta
태그에link
태그를 작성해야 함.
또한 초기 렌더링 리소스에 해당하지 않는 CSS는
media
어트리뷰트에 미디어 쿼리를 사용하여 비차단 요소로 분류되도록 명시함.
script
태그를 만나면 자바스크립트 엔진이 스크립트 실행을 모두 마칠 때까지 DOM 파싱을 중단하므로, 스크립트 실행을 우선해야할 상황이 아니라면 DOM 파싱이 모두 완료된 이후에 script
태그를 만나도록 해야함.
script
태그를body
태그 하단에 작성.
(webpack 등의 번들러 플러그인이 빌드된 스크립트를body
태그 하단에서 불러오도록 HTML을 후처리하는 이유)
만일
src
어트리뷰트로 스크립트를 로드하며 동시에 DOM 파싱이 중단되지 않고 병렬 처리되길 원한다면,async
나defer
어트리뷰트를 사용함.
async
와defer
의 공통점: DOM 파싱을 중단하지 않고 외부 스크립트를 비동기적으로 로드.- 차이점: 스크립트의 실행 시기. (
async
: 스크립트 로드가 완료된 직후, DOM 생성을 중단 후 실행.defer
: DOM 생성이 완료되면 실행.)
리렌더링 자체를 안할 수는 없을 것입니다. 렌더링 과정에서나 혹은 사용자 인터렉션에 따라서 현재 페이지에서 렌더 요소를 변경시켜야 하는 일이 흔하게 벌어지기 때문입니다.
JavaScript에서 DOM API를 통하여 DOM 요소나 CSSOM 요소를 조작하면 렌더 트리가 재합성되어 리렌더링이 이루어집니다.
CRP 리렌더링 과정 중 컴퓨팅 파워를 많이 소모하는 단계를 순위로 매기면, 1위는 리플로우, 2위는 리페인트, 3위는 컴포지션입니다. 특히 컴포지션은 CPU를 사용하는 다른 두 단계와 달리 GPU를 사용하기 때문에 CPU와 GPU의 병렬 작업으로 성능상 이점이 있습니다.
염두에 두어야 할 점은, 리렌더링 과정에서 세 단계를 반드시 모두 거치지는 않는다는 것입니다. 갱신이 필요한 단계만 거치게 됩니다.
따라서 각 단계를 일으키는 요인을 파악한다면, 성능에 악영향을 끼치는 작업을 자제하거나, 동일한 기능을 구현하되 성능 하락을 방지할 수도 있습니다.
리플로우가 일어나는 대표적인 속성: 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