서비스 운영자들은 웹 사이트를 이용하는 유저의 경험(UX, User Experience)을 향상시키기 위해 다양한 노력들을 기울입니다. 사용자 경험이 불편한 웹사이트는 사이트 이용시간을 단축시키거나, 재사용성을 떨어트릴 수 있습니다.
Web Vitals
은 좋은 사용자 경험을 제공하기 위해 어떤 점을 개선시켜야 하는지에 대한 통합 최적화 지표입니다.
First Input Delay(최초 입력 지연, FID)란 사용자가 페이지와 처음 상호 작용할 때(링크를 클릭하거나 버튼을 탭 하거나 사용자 지정 JavaScript 기반 컨트롤을 사용할 때)부터 해당 상호 작용에 대한 응답으로 브라우저가 실제로 이벤트 핸들러 처리를 시작하기까지의 시간을 측정하는 지표입니다.
FID는 이벤트 처리에서 "지연" 부분만 측정하며 이벤트 처리 시간 자체나 브라우저에서 이벤트 핸들러를 실행한 후 UI를 업데이트하는 데 걸리는 시간은 측정하지 않습니다. 이 시간은 사용자 경험에 영향을 미치지만 이를 FID의 일부로 포함하는 경우 개발자는 이벤트에 비동기적으로 응답하는 방향으로 유도됩니다. 이러한 방식은 메트릭 자체는 개선하지만 경험은 악화시킬 수 있습니다.
열악한 FID의 주요 원인은 과도한 JavaScript 실행입니다. JavaScript가 웹 페이지에서 구문 분석, 컴파일 및 실행하는 방식을 최적화하면 FID가 감소합니다.
브라우저는 메인 스레드에서 JavaScript를 실행하는 동안 대부분의 사용자 입력에 응답할 수 없습니다. 즉, 메인 스레드가 사용 중인 경우 브라우저는 사용자 상호 작용에 응답할 수 없다는 의미입니다. 이를 개선하기 위한 방법은 다음과 같습니다.
Total Blocking Time(TBT)는 로드 반응성을 체크하는데 중요한 지표입니다.
❓ 로드 반응성이란?
👉 구성 요소가 사용자 상호 작용에 빠르게 응답하기 위해 페이지에서 필요한 JavaScript 코드를 얼마나 빠르게 로드하고 실행할 수 있는지를 확인합니다.
Google에서 제공하는 Lighthouse 툴을 이용해서 TBT를 측정할 수 있습니다. 아래는 Naver 사이트를 Lighthouse로 측정해본 값입니다.
FID는 코드 분할 및 긴 작업 세분화와 같은 모범 사례를 채택하면 눈에 띄게 개선됩니다. TBT는 필드 메트릭이 아니지만 궁극적으로 Time To Interactive(상호 작용까지의 시간, TTI)와 FID를 모두 개선하기 위한 진행 상황을 확인하는 데 유용합니다.
web.dev에서 FID를 최적화 하는 방법론을 설명하고 있습니다.
50ms 이상 메인 스레드를 차단하는 모든 코드는 긴 작업이라고 보고 분할해준다. 번들을 여러 청크로 코드 분할. 주어진 긴 작업의 차단 시간은 50ms를 초과해 지속됩니다. 또한 페이지의 총 차단 시간은 FCP와 TTI 사이에서 발생하는 각각의 긴 작업에 대한 차단 시간을 합한 것입니다. 즉, 아래에서 50ms를 뺀 총 차단시간은 345ms가 된다.
async
또는 defer
를 사용하여 타사 스크립트를 비롯한 중요하지 않은 JavaScript 지연. async
와 defer
스크립트는 다운로드 시 페이지 렌더링을 막지 않는다는 공통점이 있습니다. 따라서 async와 defer를 적절히 사용하면 사용자가 오래 기다리지 않고 페이지 콘텐츠를 볼 수 있게 할 수 있습니다.
사용하지 않는 Polyfills를 최소화한다.
Babel을 변환기로 사용하는 경우, @babel/preset-env를 사용하여 타겟팅하려는 브라우저에 필요한 Polyfills만 포함합니다. Babel 7.9의 경우 bugfixes 옵션을 활성화하여 불필요한 Polyfills을 더 줄일 수 있습니다.
Cumulative Layout Shift(누적 레이아웃 이동, CLS)은 사용자가 예상치 못한 레이아웃 이동을 경험하는 빈도를 수량화하므로 시각적 안정성을 측정할 때 중요한 사용자 중심 메트릭입니다. CLS가 낮으면 우수한 사용자 경험을 보장하는 데 도움이 됩니다.
사용자 입력 0.5초(500ms)이내에 발생하지 않는 레이아웃 이동에 대한 점수를 합산하여 콘텐츠의 불안정성을 측정한다. 브라우저는 렌더링된 두 개의 프레임 사이 뷰포트의 크기와 뷰포트 내 불안정 요소의 움직일을 살펴, 해당 움직임에 대한 impact fraction 과 distance fraction 의 값을 가지고 레이아웃 이동 점수를 구한다.
layout shift score = impact fraction * distance fraction
impact fraction
불안정 요소가 두 프레임 사이 뷰포트 영역에 미치는 영향을 측정
위 이미지에는 한 프레임에서 뷰포트의 절반을 차지하는 요소가 있다. 다음 프레임에서는 요소가 뷰포트 높이의 25%만큼 아래로 이동한다. 빨간색
점선 직사각형은 두 프레임 모두에서 요소의 가시 영역을 합한 것으로 전체 뷰포트의 75%이다. 그래서 impact fraction은 0.75이다.
distance fraction
프레임에서 불안정 요소가 수평 또는 수직으로 이동한 최대 거리를 뷰포트 너비 또는 높이 중 더 큰 값으로 나눈 값이다.
위 이미지에서 가장 큰 뷰포트 값은 높이이고, 불안정한 요소는 뷰포트 높이의 25%만큼 이동하였으므로 distance fraction은 0.25이다.
👉 레이아웃 이동점수 = 0.75*0.25 = 0.1875 이다.
First Contentful Paint(FCP)는 사용자가 화면에서 콘텐츠를 볼 수 있는 페이지 로드 타임라인의 첫 번째 지점을 표시하기 때문에 사용자가 감지하는 로드 속도를 측정하는 지표입니다.
페이지가 로드되기 시작한 시점부터 페이지 콘텐츠의 일부가 화면에 렌더링 될 때까지의 시간을 측정합니다. 텍스트, 이미지를 포함합니다. 위의 두 번째 프레임에서 FCP가 발생합니다.
좋은 FCP 점수란? 👉 1.8초 이하
import {getFCP} from 'web-vitals';
// FCP를 이용 가능하게 되면 바로 측정 및 기록
getFCP(console.log);