Show
What got you here won't get you there성능 최적화 본문Web App 성능 최적화optimy 2021. 9. 6. 06:19 TOAST UI의 성능 최적화를 보고 정리한 글입니다. 목차성능 최적화에 필요한 이론과 측정 도구
웹 페이지 로딩 최적화
웹 페이지 렌더링 최적화
맺음말성능 최적화에 필요한 이론과 측정 도구브라우저의 로딩 과정을 다루고, 각 과정에서 사용되는 용어와 성능을 측정하는 데에 사용되는 지표를 설명한다. 성능 측정 도구로 크롬 개발자 도구를 살펴본다. 브라우저의 로딩 과정브라우저는 웹 페이지에 필요한 리소스를 내려받고 해석한 다음 여러 계산 과정을 거쳐 콘텐츠를 화면에 보여준다. 이를 브라우저의 로딩 과정이라고 하며 다운로드, 파싱, 스타일, 레이아웃, 페인트, 합성으로 나뉜다.
위의 5단계를 CRP(Critical Rendering Path, 주요 렌더링 경로)라고 부른다. 위 5단계를 수행하는 과정을 렌더링 과정이라고 하는데, 이는 상황에 따라 반복해서 발생할 수 있다. 예를 들어, DOM에 새로운 요소가 추가되어 DOM 트리를 재구성하거나, CSS 속성 값이 변경되어 CSSOM 트리를 재구성하는 경우, 렌더 트리가 재구성된다. 렌더 트리가 재구성되면서 요소에 기하적인 영향(높이, 넓이, 위치)이 있을 경우 레이아웃 이후의 과정을 다시 진행한다. 이를 리플로우(Reflow)라고 한다. 만약 렌더 트리가 재구성 되었을 때, 기하적인 변화가 없었다면 레이아웃 과정을 생략하고 페인트 과정부터 수행하며 이를 리페인트(Repaint)라고 한다. 레이아웃이 일어나면 전체 픽셀을 다시 계산해야 하므로 부하가 크다. 그에 비해서 리페인트는 이미 계산된 값을 이용해 화면을 그리므로 상대적으로 부하가 적다. 블록 리소스와 주요 렌더링 경로브라우저 로딩 초기 단계에서 HTML 파싱이 일어날 때 CSS 또는 자바스크립트로 인해 파싱이 중단될 수 있다. 이를 HTML 파싱 블로킹이라고 표현하며, 블로킹의 원인이 되는 리소스를 블록 리소스(Block resource)라고 부른다. 블록 리소스는 페인트 과정을 지연시키므로, 블록 리소스가 HTML 파싱을 막는 상황이 발생하지 않도록 해야한다. 이를 주요 렌더링 경로 최적화라고하며 이를 통해 페인팅을 빠르게 하고 로딩 속도를 개선할 수 있다. 성능 개선 지표로딩 속도가 느린지를 어떤 기준으로 판단할 수 있을까? 성능 지표의 측정 기준은 크게 브라우저와 사용자로 나눌 수 있다. 브라우저 기준의 성능 측정전통적인 성능 측정 방식은 브라우저에서 발생하는 이벤트를 사용하는 것이었다. 웹 페이지가 로딩될 때 DOMContentLoaded, load 이벤트가 발생하며, 각 이벤트가 발생하는 시점으로 성능을 측정하게 된다. 두 이벤트의 발생 시점이 빠를 수록, 이벤트 발생 구간의 폭이 좁을 수록 성능이 좋다고 할 수 있다. DOMContentLoaded
load
개발 패러다임이 변화하면서 DOMContentLoaded, load 이벤트 발생 시점만 가지고 성능을 판단하기 어려워졌다. 최근 많이 사용되는 SPA(Single Page Application)에서는 웹 페이지에 적은 양의 HTML로 DOMContentLoaded, load 이벤트가 일찍 발생할 수 있으나, 이후에 수많은 스크립트 실행으로 인해 여전히 "느린 로딩"이 존재한다. 따라서 새로운 성능 측정 방식이 필요하게 되었다. 사용자 기준의 성능 측정사용자 기준의 성능 측정은 사용자에게 콘텐츠를 보여주는 여러 시점을 기반으로 한다. 의미 있는 콘텐츠가 처음 보이는 시점이 빠를 수록 성능이 좋다고 판단하며, 이 시점을 앞당길 수 있도록 최적화 해야한다. 구글에서는 사용자가 웹 페이지 로딩이 빠르다, 느리다를 느낄 수 있는 여러 순간을 정의하고 성능을 측정하는 지표로 사용한다. FP(First Paint)
FCP(First Contentful Paint)
FMP(First Meaningful Paint)
LCP(Largest Contentful Paint)
TTI(Time to Interactive)
이 중 가장 중요한 시점은 FMP인데, 로딩이 끝날 때까지 흰 화면 대신 의미 있는 콘텐츠를 먼저 보여주어 사용자 입장에서 성능을 좋게 느끼게 한다. FMP를 앞당기기 위해서는 주요 렌더링 경로를 최적화하여 해결한다. 과거(2019년 이전)에는 FMP를 주요 지표로 사용했지만 복잡하고, 설명하기 힘들고, 메인 콘텐츠가 로드되는 시점을 종종 틀리기 때문에, W3C Web Performance Working Group에서의 회의와 구글의 조사에 따라서, 더 정확하게 페이지의 주요 콘텐츠가 로드되는 순간을 위한 지표로 LCP를 사용한다. (참고) 성능 측정 도구크롬 브라우저에서는 개발자 도구를 제공하며, 이를 사용해 위에서 설명한 내용을 눈으로 확인할 수 있다. 성능과 관련된 패널로는 Network, Performance, Lighthouse 등이 있다. Performance 패널
Network 패널
리소스의 서버 요청 대기 시간
Lighthouse 패널
웹 페이지 로딩 최적화주요 렌더링 경로를 기반으로 최적화를 진행해보자. 블록 리소스(CSS, 자바스크립트) 최적화브라우저 로딩 과정에서 파싱 중 블로킹이 일어날 수 있으며, CSS와 자바스크립트가 블록 리소스에 해당한다고 했다. 최적화의 첫 번째 단계는 이 블록 리소스를 최적화하는 것이다.
리소스 요청 수 줄이기CSS, 자바스크립트, 이미지 등 웹 페이지에 포함된 리소스는 서버 요청 후 다운로드되어야 사용할 수 있다. 리소스 파일 하나를 요청하는 데 많은 시간이 소요(요청에 필요한 시간)되므로, 필요한 요청만 할 수 있도록 최적화 해야 한다.
리소스 용량 줄이기용량이 큰 리소스도 웹 페이지 로딩 시간(다운로드에 필요한 시간)을 느리게 하는 원인이 된다. 각 리소스에 맞게 불필요한 데이터를 제거하고 압축하여 사용하는 것이 좋다.
웹 페이지 렌더링 최적화웹 페이지를 렌더링하기 위해서는 DOM과 CSS가 필요하다. 그러나 다양한 기능과 효과를 구현하기 위해서 자바스크립트를 많이 사용하기 때문에, 자바스크립트가 렌더링 성능에 어떤 영향을 주는지 잘 알아야한다. 또한 자바스크립트는 브라우저에서 단일 스레드로 동작하기 때문에 자바스크립트의 실행 시간은 곧 렌더링 시간과 직결된다. 렌더링은 자바스크립트의 실행 시간과 자바스크립트로 인한 DOM, CSS 변경을 다시 화면에 그리는 시간을 모두 포함한다. 렌더링 성능 최적화는 이러한 소요 시간을 단축하고 화면에 끊김 없이 그리는 것이다. 레이아웃 최적화렌더링 과정에서 레이아웃은 DOM 요소들이 화면에 어느 위치에 어떤 크기로 배치될지를 결정하게 되는 계산 과정이다. 자바스크립트 코드를 통해 DOM을 변경하거나 스타일을 변경할 경우, 변경된 스타일을 반영하고 다시 레이아웃을 해야만 화면에 렌더링할 수 있다. 레이아웃은 글자의 크기를 일일이 계산하고 요소 간 관계를 모두 파악해야 하는 과정이므로 시간이 오래 걸린다. 레이아웃 최적화의 목표는 자바스크립트의 실행 과정과 렌더링이 다시 일어나는 과정에서 레이아웃에 걸리는 시간을 단축하고 레이아웃이 최대한 발생하지 않도록 하는 것이다. 자바스크립트 실행 최적화자바스크립트 실행 시간이 긴 경우, 한 프레임 처리가 오래 걸려 렌더링 성능이 떨어진다. 많은 작업을 수행하는 경우 당연히 오래 걸리지만, 코드가 단순하더라도 불필요한 레이아웃으로 성능 저하가 생길 수 있다. 레이아웃을 줄일 수 있도록 DOM 및 스타일 변경을 최소화해야 한다.
HTML, CSS 최적화화면을 렌더링하기 위해서 필요한 데이터는 HTML과 CSS로, 각각 DOM 트리와 CSSOM 트리를 만들고 렌더링할 때 사용된다. DOM 트리와 CSSOM 트리를 변경하면 렌더링을 유발하고 트리가 클 수록 더 많은 계산이 필요하다. 그러므로 HTML과 CSS를 최적화하여 렌더링 성능을 향상할 수 있다.
애니메이션 최적화한 프레임 처리가 16ms(60fps) 내로 완료되어야 렌더링 시 끊기는 현상 없이 자연스러운 렌더링을 만들 수 있다. 자바스크립트 실행 시간은 10ms 이내에 수행되어야 레이아웃, 페인트 등의 과정을 포함했을 때 16ms 이내에 프레임이 완료될 수 있다. 애니메이션을 구현할 때 네이티브 자바스크립트 API를 사용하는 것보다 CSS 사용을 권장한다. (자바스크립트 실행의 부하를 줄이기 위해서)
맺음말2019년에 작성된 글을 보면서 브라우저의 렌더링 과정을 다시 훓어 보면서 렌더링 엔진과 최적화의 중요성을 다시금 느낄 수 있었다. 기존 크롬의 개발자 도구의 여러 패널들을 잘 활용하지 못했는데, 이 기회에 공부할 수 있어서 좋았고, 구글의 웹 표준에 대한 다양한 논의를 찾아보면서 개발 생태계가 발전하고 있음을 느낄 수 있었다. |