[Web.dev] Fast (2) - Performance Budget

2022. 4. 22. 11:48Frontend

 

 

Overview

web.dev에서 소개하는 Web Security에 대한 내용들을 여러 챕터에 걸쳐서 정리합니다. 모든 내용들을 다 다루지는 않고, 개인적으로 중요하다고 생각하는 부분들을 추려서 중점적으로 정리했습니다. 자세한 내용들은 아래 Table of Contents의 링크를 통해 확인하실 수 있습니다.

 

성능 예산 수립

 

Performance Budget

performance budget이란, 사이트의 퍼포먼스를 측정하기 위한 여러 기준들을 의미합니다. 이전 포스팅에서도 언급했듯, 사이트의 퍼포먼스를 측정하는 기준은 사용하는 유저에 따라, 적용 환경에 따라 다양할 수 있기 때문에 여러 기준들을 정해두고, 상황에 가장 적합한 기준들을 고려하는 것이 중요합니다. 자주 사용되는 기준(budget)들은 다음과 같습니다.

 

  • total size of a page
  • time it takes to load on a mobile network
  • number of HTTP Requests that are sent

 

페이지의 사이즈(용량), 모바일 네트워크 환경(3G 네트워크 환경)에서의 로딩 시간, 웹 페이지가 사이트를 로딩하는데 필요한 HTTP Request의 개수들을 적절하게 정해두고 사이트의 퍼포먼스를 측정할 수 있습니다. 이외에도 아래에서 소개할 FCP, LCP, TTI와 같은 지표들을 가지고 실제로 "사용자의 측면"에서 원하는 화면을 보고, 원하는 동작을 수행하는 데 걸리는 시간들을 측정함으로써, 보다 실질적인 사이트의 퍼포먼스도 측정할 수 있습니다.

 

 

First Contentful Paint(FCP)

 

 

FCP는 페이지가 로드되기 시작한 시점부터 페이지 콘텐츠의 "일부"가 화면에 렌더링 될 때까지의 시간을 측정합니다. 다만 이 메트릭에서 "콘텐츠"란 텍스트, 이미지(배경 이미지 포함), svg요소, 또는 "흰색이 아닌" canvas 요소를 의미합니다. 

 

위의 그림에서 확인할 수 있듯이, 실제로 FCP지표가 좋게 나온다고 하더라도 사용자 입장에서는 콘텐츠의 "일부"만 보일 수 있기 때문에 화면 전체가 그려지는 시간을 측정하지는 못합니다. 이를 조금 보완하기를 원한다면 아래의 LCP를 사용할 수 있습니다.

 

https://web.dev/i18n/ko/fcp/

 

First Contentful Paint(최초 콘텐츠풀 페인트, FCP)

이 게시물에서는 최초 콘텐츠풀 페인트(FCP) 메트릭을 소개하고 이를 측정하는 방법을 설명합니다.

web.dev

Largest Contentful Paint(LCP)

 

 

LCP는 페이지가 처음 로드를 시작한 기준으로 "뷰포트(viewport)"내에 있는 가장 큰 이미지 또는 텍스트 블록의 렌더링 시간을 측정합니다. 따라서 "사용자의 입장"에서 보다 효과적인 지표로 이해할 수도 있습니다.

 

https://web.dev/lcp/

 

Largest Contentful Paint(최대 콘텐츠풀 페인트, LCP)

이 게시물에서는 최대 콘텐츠풀 페인트(LCP) 메트릭을 소개하고 이를 측정하는 방법을 설명합니다.

web.dev

 

Time To Interactive (TTI)

TTI는 페이지가 완전히 상호작용이 가능하게 되는데 걸리는 시간을 측정합니다. 여기서의 "상호작용"가능하다는 것은 다음의 경우를 의미합니다.

 

  • 페이지에 FCP에 의해 측정되는 유용한 콘텐츠가 표시되어야 합니다.
  • 가장 많이 보이는 페이지 요소에 이벤트 핸들러가 등록되어야 합니다.
  • 페이지가 50ms이내에 사용자와의 상호 작용에 응답해야 합니다.

 

일부 사이트에서는 상호작용을 희생하면서 Content Visibility를 최적화하는 경우고 있기 때문에 TTI도 같이 측정하는 것은 중요합니다. FCP, LCP가 빠르지만 TTI가 느린 경우에는 좋은 사용자 경험을 주지 못할 가능성이 높습니다. (즉 사이트가 준비된 것"처럼" 보이게 됩니다.)

 

https://web.dev/interactive/

 

상호 작용까지의 시간

Lighthouse의 상호 작용까지의 시간 메트릭과 이를 측정하고 최적화하는 방법에 대해 알아봅니다.

web.dev

 

Browser Event

사용자의 입장에서 FCP, LCP, TTI를 최적화하는 것 이외에 브라우저가 페이지를 보여주는 방식을 최적화하기 위해서는 Critical Rendering Path를 최적화하는 작업도 필요합니다. 이 Critical Rendering Path를 올바르게 최적화하기 위해서는 실제로 브라우저가 페이지를 요청하는 단계부터 HTML을 파싱 하고 스크립트를 로드해서 실행하고, 스타일시트를 입혀서 페인트 하는 일련의 과정들을 이해하고 있어야 하며, 이 Critical Rendering Path의 내용은 지면이 조금 길어질 수 있어 이후 포스팅에서 다루도록 하고, 이번 포스팅에서는 중요한 개념 중 하나인 DOMContentLoadedLoad 이벤트에 대해서만 다루도록 하겟습니다.

 

 

 

DOMContentLoaded

DOMContentLoaded 이벤트는 브라우저가 HTML을 전부 읽고 DOM Tree를 완성하는 즉시 발생하게 됩니다. 따라서 css, image, script 등의 기타 자원을 기다리지 않고 내부적으로 DOM Tree만 완성되면 이 이벤트가 발생합니다. 

 

DOM이 완성된 이후에 발생하는 이벤트 이므로 이 이벤트가 발생하는 시점에는 document 객체가 완성되어 있다고 볼 수 있으며, 따라서 DOMContnetLoaded 이벤트가 발생한 이후에, 생성된 document 객체에 이벤트 리스너를 붙일 수 있습니다. 실제로 Firefox, Chrome, Opera 등의 브라우저에서 폼 자동완성(Form Autofill) 기능을 제공하는데 이러한 기능을 구현하기 위해 이 DOMContentLoaded 이벤트를 사용합니다. (해당 이벤트 발생 이후, document 객체에 이벤트 핸들러를 부착하는 방식으로)

 

스크립트의 경우에는 css img의 경우와는 경우에 따라서 조금 다르게 작동할 수 있는데 기본적으로 스크립트는 API를 통해 DOM 노드를 직접 조작할 수 있기 때문에 "defer" 속성을 사용하지 않는 한, HTML 파싱을 중단시킵니다. (스크립트에 대한 자세한 내용은 이전 포스팅을 참고해주세요) 따라서 중간에 스크립트가 있으면 이 스크립트를 먼저 처리한 이후에 DOMContentLoaded 이벤트가 발생하게 됩니다.

 

Load

Load 이벤트는 HTML로 DOM트리를 만드는 과정이 완성되었을 뿐 아니라, css, image 같은 외부 자원들도 모두 불러온 후에 발생합니다. DOM Tree만 생성되었을 때 발생하는 DomContentLoaded 이벤트와는 다르게 css와 같은 요소들이 모두 불러와진 이후에 발생하기 때문에 실제로 화면에 그려지는 요소들의 실제 크기들에 접근할 수 있게 됩니다. 이로 인해 필연적으로 DOMContentLoaded 이벤트가 발생한 이후에 발생하게 되며, 웹뷰의 경우 클라이언트에서 해당 이벤트가 발생하기 전까지 Spinner를 돌리다가 해당 이벤트 발생 이후에 Spinner를 제거하는 경우도 많으므로 웹뷰 로딩 속도를 빠르게 하기 위해서는 이 Load 이벤트를 느리게 만드는 요인을 파악해서 해결하는 것이 중요합니다.

 

 

 

Reference

https://ko.javascript.info/onload-ondomcontentloaded

 

DOMContentLoaded, load, beforeunload, unload 이벤트

 

ko.javascript.info

 

반응형

'Frontend' 카테고리의 다른 글

[Nextjs] How Image Optimization Works  (2) 2022.04.30
[Web.dev] Fast (3) - Image Optimization  (0) 2022.04.30
[Web.dev] Fast (1) - Introduction  (0) 2022.04.15
[Web] preload, prefetch, preconnect  (0) 2022.04.03
[Javascript] script async & defer  (1) 2022.04.02