웹사이트 성능 메트릭

Yuri Na·2021년 3월 8일
33

https://yrnana.dev/post/2021-03-09

주요 metrics(지표) 항목

⭐️ 표시는 Web Vital에서 중점적으로 체크하는 항목이다.

  • LCP : 로딩 성능
  • FID : 상호 작용력
  • CLS : 시각적 안정성

TTFB (Time To First Byte)

페이지를 요청했을 때 서버에서 데이터의 첫 번째 바이트가 도착하는 시점을 나타낸다. TTFB는 주로 서버 성능과 직결된다.

최적화 방법

  • 서버 애플리케이션 로직 최적화
  • DB 쿼리 최적화 또는 더 빠른 DB로 마이그레이션
  • 더 많은 RAM 또는 CPU를 갖도록 서버 하드웨어 업그레이드

FCP (First Contentful Paint)


FCP는 페이지가 로드되기 시작하고 컨텐츠의 일부가 화면에 렌더링 될 때 까지의 시간을 의미한다.

최적화 방법

  • 렌더링을 block 하는 리소스 제거
  • CSS minify
  • 사용하지 않는 CSS 제거
  • 요청할 origin에 preconnect : <link rel="preconnect">
  • 서버 응답 시간 (TTFB) 줄이기
  • 여러 페이지 리다이렉트 줄이기
  • 키 요청 preload : <link rel="preload">
  • 지나치게 큰 네트워크 payload를 피하기
  • 효율적인 캐시 정책으로 정적 자산 제공
  • 과도한 DOM size를 피하기
  • 중요한 요청의 depth를 최소화
  • 웹 폰트 로드 중에 텍스트가 계속 보이도록 함
  • 요청 수를 줄이고 전송 크기를 작게 하기

FMP (First Meaningful Paint)

브라우저가 페이지의 주요 컨텐츠들을 화면에 렌더링하기 시작하는 순간이다. 다만, FMP는 페이지 로드의 작은 차이에 지나치게 민감하기 때문에 일관성이 떨어져서 LCP를 측정하는 것을 권장하고 있다.

⭐️ LCP (Largest Contentful Paint)


페이지에서 가장 용량이 큰 컨텐츠가 표시되는 시점을 나타낸다. FCP의 경우 페이지에 스플래시 화면이 표시되거나 로딩중 아이콘이 표시되는 경우도 포함하기 때문에 사용자와 그다지 관련이 없다. FMP를 측정하는 것이 복잡하기 때문에 가장 용량이 큰 컨텐츠가 렌더링 되는 시기인 LCP를 주요 컨텐츠가 로드되는 시기로 판단하는 것을 권장하고 있다.

최적화 방법

  • 느린 서버 응답 시간 해결
    • 서버 최적화
    • 가까운 CDN으로 라우팅
    • asset 캐싱
    • cache-first HTML 페이지 서빙
    • 서드파티 origin 리소스 preconnect
  • 렌더링을 block 하는 JS 및 CSS 해결
    • CSS block 시간 단축
      • CSS minify
      • 중요하지 않은 CSS는 defer로 load
      • 중요 CSS는 inline 으로 load
    • Javascript block 시간 단축
      • JS 파일 minify 및 압축
  • 느린 리소스 (img, svg, video, ...) 로드 시간 해결
    • 이미지 최적화 및 압축
    • 중요한 리소스 preload
    • 텍스트 파일 압축
    • 적응형 리소스 서빙
      • 예: 네트워크가 느린 경우 video 대신 image 서빙
    • 서비스 워커를 통한 자산 캐싱
  • 클라이언트 사이드 렌더링의 경우
    • 중요한 자바스크립트 최소화
      • 자바스크립트 minify
      • 사용하지 않는 자바스크립트 defer로 load
      • 사용하지 않는 polyfill 최소화
    • 서버사이드 렌더링 사용
      • TTFB 증가, TTI 증가를 고려해야 함
    • pre-rendering 사용
      • TTI는 증가할 수 있으나 TTFBSSR보다 나음

⭐️ CLS (Cumulative Layout Shift)


페이지가 로드되기 시작하는 시점과 lifecycle 상태가 숨김으로 변경되는 시점 사이에 발생하는 모든 예기치 않은 레이아웃 이동의 누적 점수를 측정한다. 일반적으로 리소스가 비동기적으로 로드되거나 DOM 요소가 기존 컨텐츠가 있는 페이지에 동적으로 추가될 때 발생한다.

최적화 방법

  • 이미지나 동영상 요소에 크기를 미리 지정하거나 임시 박스같은 것으로 필요한 공간을 확보
  • 사용자 interactive 응답 외에 기존 컨텐츠 위에 컨텐츠를 넣지 않기
  • layout 변경을 트리거하는 css property보다 transform 애니메이션을 사용

TTI (Time To Interactive)

웹 페이지가 완전히 상호작용이 가능(interactive)하게 되는 시점을 나타낸다. 컨텐츠를 볼 수 있지만 스크롤 할 수 없거나 항목을 클릭해도 효과가 없으면 interactive 하지 않은 것이다.

최적화 방법

  • JS minify
  • 요청할 origin에 preconnect : <link rel="preconnect">
  • 키 요청 preload : <link rel="preload">
  • 타사 코드의 영향 범위 감소
  • 중요한 요청의 depth를 최소화
  • JS 실행시간 단축
  • 메인 스레드 작업 최소화
  • 요청 수를 줄이고 전송 크기를 작게 유지

⭐️ FID (First Input Delay)


사용자가 페이지와 처음 상호작용한(클릭 또는 키 입력 등) 시간부터 브라우저가 실제로 이벤트 핸들러 처리를 시작할 수 있는 시간까지의 시간을 측정한다.

일반적으로 입력 지연은 브라우저의 기본 스레드가 다른 작업 (예: 대용량 js 파일 파싱)을 실행 중일때 발생한다. 위와 같이 메인 스레드에서 작업중인데 user input이 발생하면 브라우저가 이에 대응하는데 FID만큼의 시간이 소요된다.

최적화 방법

  • 긴 Tasks 분할하기
    • 메인 스레드를 50ms 이상 차단하는 긴 Task를 분할하기 (TBT 개선)
    • 코드 스플리팅
  • 상호작용 준비를 위한 페이지 최적화
    • JS 코드 및 기능을 점진적으로 load
    • SSR의 경우 논리를 서버측으로 이동하고 코드 스플리팅을 고려해야 함
    • cascading data fetch를 최소화
    • 서드파티 코드 로딩시간 고려해야 함
  • web worker 사용하기
    • 백그라운드 스레드에서 자바스크립트를 실행할 수 있음
  • JS 실행시간 단축
    • 사용하지 않는 자바스크립트 defer로 load
      • 특별한 이유가 없는 한 서드파티 스크립트는 defer 또는 async로 로드되어야 함
    • 사용하지 않는 polyfill 최소화
      • module / nomodule 패턴을 활용하여 개별 번들 제공

TBT (Total Blocking Time)


TBT는 주 스레드가 input 응답을 막을 정도로 오래 차단 되었을때 FCPTTI 사이의 총 시간을 나타낸다. 긴 작업의 차단 시간은 50ms를 초과하는 시간으로 계산한다. 즉 task의 작업 시간이 250ms이면 TBT는 200ms이다.

최적화 방법

  • 타사 코드의 영향 범위 감소
  • JS 실행시간 단축
  • 메인 스레드 작업 최소화
  • 요청 수를 줄이고 전송 크기를 작게 유지

SSR과 CSR에서의 성능 메트릭

SSR (Server Side Rendering)

SSR은 일반적으로 빠른 FPFCP를 가진다. 또한 많은 JS를 서버단에서 실행하므로 TTI도 빠르게 수행할 수 있다. 다만 서버에서 페이지를 생성하는데 시간이 걸리기 때문에 TTFB가 느려질 수 있다.

SSR with hydration

유려한 페이지 전환과 인터랙션을 위해 첫 페이지 렌더는 SSR, 이후에는 CSR로 이루어지는 SSR with hydration이라는 기법도 존재한다. Next.js를 활용하면 쉽게 구현할 수 있다.

CSR (Client Side Rendering)

CSR에서는 리소스를 가져오기만 하면 되기 때문에 빠른 TTFB를 가진다. 하지만 FCP가 느리고 자연히 TTI는 그보다 더 느리다는 단점이 있다.

측정방법

참고

profile
Frontend Developer@Kakaopay | https://yrnana.dev

0개의 댓글