장경은
Study

[12장] 모든 웹 개발자가 관심을 가져야 할 핵심 웹 지표

웹사이트와 성능

  • 웹사이트의 성능은 사용자 경험에 큰 영향을 미친다.
  • 1초 내로 로딩되는 사이트는 5초 내로 로딩되는 사이트보다 전자상거래 전환율(실제 구매로 이어지는 고객의 비율)이 2.5배 더 높다.
  • 0 ~ 5초의 범위에서, 1초 로딩이 늦어질수록 전환율은 4.42%씩 떨어진다. 즉, 5초 이상 느려지면 전환율은 20% 가까이 떨어진다.
  • 페이지 로드 시간이 0 ~ 2초 사이인 페이지에서 가장 높은 전환율을 달성할 수 있다.

핵심 웹 지표

  • 핵심 웹 지표(외국에서는 Core Web Vital로 알려져 있다)란 구글에서 만든 지표로, 웹사이트에서 뛰어난 사용자 경험을 제공하는 데 필수적인 지표를 일컫는 용어다.
  • 구글에서 핵심 웹 지표로 꼽는 지표는 다음과 같다.
    • 최대 콘텐츠풀 페인트(LCP: Largest Contentful Paint)
    • 최초 입력 지연(FID: First Input Delay)
    • 누적 레이아웃 이동(CLS: Cumulative Layout Shift)
  • 그리고 다음 두 지표는 핵심까지는 아니지만, 특정 문제를 진단하는 데 사용될 수 있다고 언급했다.
    • 최초 바이트까지의 시간(TTFB: Time To First Byte)
    • 최초 콘텐츠풀 시간(FCP: First Contentful Paint)

최대 콘텐츠풀 페인트 (LCP)

  • 최대 콘텐츠풀 페인트(LCP: Largest Contentful Paint)란 페이지가 처음으로 로드를 시작한 시점부터 뷰포트 내부에서 가장 큰 이미지 또는 텍스트를 렌더링하는 데 걸리는 시간을 말한다.
  • 각 엘리먼트가 등장한 시점부터 텍스트 또는 이미작 완전히 로딩되는 시점
  • 사용자에게 있어 로딩이란 일단 뷰포트 영역에 보이는 부분을 기준으로 할 것이므로 뷰포트에 메인 콘텐츠가 화면에 완전히 전달되는 속도를 기준으로 한다면 사용자는 페이지가 로딩이 완료됐다고 체감하는 시간과 매우 비슷하게 측정할 수 있을 것이다.
  • 따라서 사용자에게 페이지의 정보를 화면에 전달하는 속도를 객관적으로 판단하기 위한 지표로 만들어진 것이 바로 최대 콘텐츠풀 페인트(LCP)다.
  • 최대 콘텐츠풀 페인트에서 좋은 점수란 해당 지표가 2.5초 내로 응답이 오는 것이다. 4초 이내로 응답이 온다면 보통, 그 이상이 걸리면 나쁨으로 판단된다.

개선 방안

  • 가능한 영역은 이미지가 아닌 텍스트로 채운다.
  • img, svg, video, css 등을 잘 취사선택해서 사용한다.
    • background-image를 비롯해서 CSS에 있는 리소스는 항상 느리다.

최초 입력 지연 (FID)

  • 웹페이지의 로딩 속도만큼 중요한 것이 웹사이트의 반응 속도다. 그리고 이러한 웹사이트의 반응성을 측정하는 지표가 바로 최초 입력 지연(FID: First Input Delay)이다.
  • 자바스크립트 실행 환경은 싱글 스레드이기 때문에 자바스크립트가 이벤트 리스너와 같은 다른 작업을 실행할 수 없어 지연이 발생한다.
  • 이벤트가 발생하는 시점에 최대한 메인 스레드가 다른 작업을 처리할 수 있도록 여유를 만들어 둬야 사용자에게 빠른 반응성을 보장할 수 있다.

[참고] 구글은 사용자 경험을 크게 4가지로 분류해 정의하는데, 이를 RAIL이라고 한다. 이 RAIL에 해당하는 것들은 다음과 같다.

  • Response: 사용자의 입력에 대한 반응 속도. 50ms 미만으로 이벤트를 처리할 것

  • Animation: 애니메이션의 각 프레임을 10ms 이하로 생성할 것

  • Idle: 유휴 시간을 극대화해 페이지가 50ms 이내에 사용자 입력에 응답하도록 할 것

  • Load: 5초 이내에 콘텐츠를 전달하고 인터랙션을 준비할 것

  • 최초 입력 지연은 R에 해당하는 응답에 초점을 맞추고 있다.

  • 최초 입력 지연의 좋은 점수를 얻기 위해서는 100ms 이내로 응답이 와야 하며, 300ms 이내인 경우 보통, 그 이후의 경우에는 나쁨으로 처리된다.

개선 방안

  • 최초 입력 지연을 개선하려면 최초 입력 지연에 가장 큰 영향을 미치는 메인 스레드에 이벤트를 실행할 여유를 줘야 한다.
  • 긴 작업이 있다면 여러 개로 분리해 처리하는 것이 좋다.
  • 당장의 로딩에 필요하지 않은 리소스는 리액트의 Suspense와 lazy, 또는 Next.js의 dynamic을 이용해 나중에 불러올 수 있다.

[참고] 크롬 개발자 도구

  • CPU 의도적으로 감소, 네트워크 속도 감속 가능
  • 커버리지: 현재까지 웹페이지에서 사용되지 않은 코드가 얼마나 있는지 확인할 수 있음.
  • 폴리필: 브라우저에서 지원하지 않는 기능을 사용하기 위해 웹페이지에서 직접 구현하고 집어넣는 코드 (e.g. 인터넷 익스플로러 11 이하 버전)

누적 레이아웃 이동 (CLS)

  • 페이지의 생명주기 동안 발생하는 모든 예기치 않은 이동에 대한 지표를 계산하는 것이 바로 누적 레이아웃 이동이다.
  • useEffect가 많을 수록, 그리고 이 useEffect가 렌더링에 영향을 미칠 수록 이 점수가 떨어질 가능성이 크다.
  • 최초 렌더링이 시작된 위치에서 만약 레이아웃의 이동이 발생한다면 누적 레이아웃 이동 점수로 기록하게 된다.
    • 또한 단순히 요소가 추가된다고 해서 무조건 누적 레이아웃 이동으로 간주되는 것은 아니다. 요소가 추가됐다 하더라도 다른 요소의 시작 위치에 영향을 미치지 않았다면 레이아웃 이동으로 간주되지 않는다.
  • 사용자 액션으로 인해 발생한 레이아웃 이동은 점수에 포함되지 않는다.
    • 사용자가 아무런 동작을 하지 않았음에도 불구하고 레이아웃 이동이 발생하는 경우에는 점수에 포함된다.

개선 방안

  • 로딩 상태임을 보여주는 스켈레톤 UI를 추가해 대략적인 페이지 레이아웃을 고정하기.
  • useLayoutEffect 훅을 사용하는 것을 검토하기
    • 그러나 useLayoutEffect는 동기적으로 발생해 브라우저의 페인팅 작업에 영향을 미치기 때문에 사용자에게 로딩이 오래 걸리는 것과 같이 보일 수 있다.
  • 폰트 로딩 최적화
    • 폰트로 인해 발생할 수 있는 문제
      • FOUT(flash of unstyled text): HTML 문서에서 지정한 폰트가 보이지 않고 대체 기본 폰트로 보이고 있다가 뒤늦게 폰트가 적용되는 현상
      • FOIT(flash of invisible text): HTML 문서에서 지정한 폰트가 보이지 않고, 기본 폰트도 없어서 텍스트가 없는 채로 있다가 뒤늦게 폰트가 로딩되면서 페이지에 렌더링되는 현상
    • 최대한 중요한 폰트의 다운로드를 우선순위에 밀어넣고, 이 우선순위를 활용했음에도 빠르게 로딩하는데 실패했다면 다음을 기약하고 기본 폰트로 노출하기.
  • 적절한 이미지 크기 설정
    • width: 100%; height: auto;로 불러온 이미지는 레이아웃 이동이 크게 발생한다.
    • width, height를 지정해주는 것이 가장 좋다.
    • 반응형 이미지를 사용하고 싶다면 srcset 속성을 사용하는 것이 좋다.

핵심 웹 지표는 아니지만 성능 확인에 중요한 지표들

최초 바이트까지의 시간 (TTFB)

  • 최초 바이트까지의 시간(Time To First Byte, TTFB)은 브라우저가 웹페이지의 첫 번째 바이트를 수신하는 데 걸리는 시간을 의미한다.
  • 이는 특히 서버 사이드 렌더링을 하고 있는 애플리케이션에서 주의 깊게 봐야 할 지표다.

최초 콘텐츠풀 페인트 (FCP)

  • 최초 콘텐츠풀 페인트(First Contentful Paint, FCP)란 페이지가 로드되기 시작한 시점부터 페이지 콘텐츠의 일부가 화면에 렌더링될 때까지의 시간을 측정한다.

[13장] 웹페이지의 성능을 측정하는 다양한 방법

애플리케이션에서 확인하기

  • CRA 이후 생성되는 reportWebVitals 함수는 웹에서 성능을 측정하기 위한 함수다.
    • CLS, FID, FCP, LCP, TTFB 를 측정하는 용도로 사용된다.
  • Next.js는 성능 측정을 할 수 있는 메서드인 NextWebVitalsMetric을 제공한다.
    • 예약어로 지정된 함수인 reportWebVitals를 생성하면 결과를 확인할 수 있다.
    • 여기서는 다음과 같은 Next.js에 특화된 사용자 지표도 제공한다.
      • Next.js-hydration: 페이지가 서버 사이드에서 렌더링되어 하이드레이션하는 데 걸린 시간
      • Next.js-route-change-to-render: 페이지가 경로를 변경한 후 페이지를 렌더링을 시작하는 데 걸리는 시간
      • Next.js-render: 경로 변경이 완료된 후 페이지를 렌더링하는 데 걸린 시간

구글 라이트하우스

  • 별도의 애플리케이션 코드 수정이나, 배포, 수집 없이도 지표를 수집할 수 있는 방법
  • FCP, LCP, CLS 외에도 TTI(Time To Interaction), Speed Index, Total Blocking Time 등의 수치를 제공한다.

WebPageTest

  • 웹사이트 성능을 분석하는 도구로 가장 널리 알려진 도구
  • https://www.webpagetest.org/에 (opens in a new tab) 접속한 다음, Site Performance를 선택한 뒤 분석을 원하는 웹사이트 주소를 입력한다. 그러고 나서 Start Test를 누르면 테스트가 시작된다.