[웹] Web Vital - FID, CLS, FCP

Yongwoo Cho·2022년 4월 27일
1

TIL

목록 보기
67/98
post-thumbnail
post-custom-banner

Web Vitals(웹 바이탈)

서비스 운영자들은 웹 사이트를 이용하는 유저의 경험(UX, User Experience)을 향상시키기 위해 다양한 노력들을 기울입니다. 사용자 경험이 불편한 웹사이트는 사이트 이용시간을 단축시키거나, 재사용성을 떨어트릴 수 있습니다. Web Vitals은 좋은 사용자 경험을 제공하기 위해 어떤 점을 개선시켜야 하는지에 대한 통합 최적화 지표입니다.

FID란?

First Input Delay(최초 입력 지연, FID)란 사용자가 페이지와 처음 상호 작용할 때(링크를 클릭하거나 버튼을 탭 하거나 사용자 지정 JavaScript 기반 컨트롤을 사용할 때)부터 해당 상호 작용에 대한 응답으로 브라우저가 실제로 이벤트 핸들러 처리를 시작하기까지의 시간을 측정하는 지표입니다.

  • 좋은 FID 점수는? 👉 100ms 이하

FID는 이벤트 처리에서 "지연" 부분만 측정하며 이벤트 처리 시간 자체나 브라우저에서 이벤트 핸들러를 실행한 후 UI를 업데이트하는 데 걸리는 시간은 측정하지 않습니다. 이 시간은 사용자 경험에 영향을 미치지만 이를 FID의 일부로 포함하는 경우 개발자는 이벤트에 비동기적으로 응답하는 방향으로 유도됩니다. 이러한 방식은 메트릭 자체는 개선하지만 경험은 악화시킬 수 있습니다.

열악한 FID의 주요 원인은 과도한 JavaScript 실행입니다. JavaScript가 웹 페이지에서 구문 분석, 컴파일 및 실행하는 방식을 최적화하면 FID가 감소합니다.


TBT

브라우저는 메인 스레드에서 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 지연. asyncdefer 스크립트는 다운로드 시 페이지 렌더링을 막지 않는다는 공통점이 있습니다. 따라서 async와 defer를 적절히 사용하면 사용자가 오래 기다리지 않고 페이지 콘텐츠를 볼 수 있게 할 수 있습니다.

  • 사용하지 않는 Polyfills를 최소화한다.

  • Babel을 변환기로 사용하는 경우, @babel/preset-env를 사용하여 타겟팅하려는 브라우저에 필요한 Polyfills만 포함합니다. Babel 7.9의 경우 bugfixes 옵션을 활성화하여 불필요한 Polyfills을 더 줄일 수 있습니다.

CLS란?

Cumulative Layout Shift(누적 레이아웃 이동, CLS)은 사용자가 예상치 못한 레이아웃 이동을 경험하는 빈도를 수량화하므로 시각적 안정성을 측정할 때 중요한 사용자 중심 메트릭입니다. CLS가 낮으면 우수한 사용자 경험을 보장하는 데 도움이 됩니다.

  • 좋은 CLS 점수는? 👉 0.1 이하

CLS

예상치 못한 레이아웃 이동이 발생하는 이유

  • 크기가 정해지지 않은 이미지
  • 동적으로 크기가 조정되는 광고 및 위젯
  • 동적으로 주입된 콘텐츠
  • 대체크기보다 크거나 작게 렌더링되는 글꼴
  • 애니메이션 및 전환

측정방법

사용자 입력 0.5초(500ms)이내에 발생하지 않는 레이아웃 이동에 대한 점수를 합산하여 콘텐츠의 불안정성을 측정한다. 브라우저는 렌더링된 두 개의 프레임 사이 뷰포트의 크기와 뷰포트 내 불안정 요소의 움직일을 살펴, 해당 움직임에 대한 impact fractiondistance fraction 의 값을 가지고 레이아웃 이동 점수를 구한다.

layout shift score = impact fraction * distance fraction
  • impact fraction
    불안정 요소가 두 프레임 사이 뷰포트 영역에 미치는 영향을 측정
    image
    위 이미지에는 한 프레임에서 뷰포트의 절반을 차지하는 요소가 있다. 다음 프레임에서는 요소가 뷰포트 높이의 25%만큼 아래로 이동한다. 빨간색
    점선 직사각형은 두 프레임 모두에서 요소의 가시 영역을 합한 것으로 전체 뷰포트의 75%이다. 그래서 impact fraction은 0.75이다.

  • distance fraction
    프레임에서 불안정 요소가 수평 또는 수직으로 이동한 최대 거리를 뷰포트 너비 또는 높이 중 더 큰 값으로 나눈 값이다.
    image
    위 이미지에서 가장 큰 뷰포트 값은 높이이고, 불안정한 요소는 뷰포트 높이의 25%만큼 이동하였으므로 distance fraction은 0.25이다.

👉 레이아웃 이동점수 = 0.75*0.25 = 0.1875 이다.

최적화

  • 이미지 및 비디오 요소에 항상 width 및 height 크기 속성을 포함하거나 CSS 가로 세로 비율 상자와 같은 방식으로 필요한 공간을 미리 확보
  • 사용자 상호 작용에 대한 응답을 제외하고는 기존 콘텐츠 위에 콘텐츠 삽입❌
  • 레이아웃 변경을 야기하는 속성의 애니메이션보다 전환 애니메이션을 사용하기

FCP란?

First Contentful Paint(FCP)는 사용자가 화면에서 콘텐츠를 볼 수 있는 페이지 로드 타임라인의 첫 번째 지점을 표시하기 때문에 사용자가 감지하는 로드 속도를 측정하는 지표입니다.

img

  • 페이지가 로드되기 시작한 시점부터 페이지 콘텐츠의 일부가 화면에 렌더링 될 때까지의 시간을 측정합니다. 텍스트, 이미지를 포함합니다. 위의 두 번째 프레임에서 FCP가 발생합니다.

  • 좋은 FCP 점수란? 👉 1.8초 이하

FCP

  • 측정방법
import {getFCP} from 'web-vitals';

// FCP를 이용 가능하게 되면 바로 측정 및 기록
getFCP(console.log);

최적화

  • React에서는 첫 FCP 를 빠르게 하기위해서 Next.js 처럼 서버가 첫 렌더를 먼저 그려주고 hydration으로 이벤트를 입히는 방법을 흔히 쓰게 된다.
  • 스켈레톤 UI를 이용하면 FP 가 더 빨라져서 사용자가 뭔가 진행 됨을 느껴 성능 향상이 된다. 레이아웃은 먼저 잡아 주기 때문에 로딩 스피너 보다도 조금 더 의미있는 렌더링이 되기 때문에 사용자 경험이 높아진다.
  • preload 선언으로 브라우저에게 우선순위를 표현하여 중요한 리소스를 미리 로드한다.
  • 기타 다른 라우팅과 덜 중요한 assets을 lazy loading 하기.
profile
Frontend 개발자입니다 😎
post-custom-banner

0개의 댓글