점점 빨라지는 세상이다. 사람들은 빠른 서비스를 원한다. 웹사이트의 응답 성능은 해당 업체의 신뢰성과도 직결되는 문제이다. 웹사이트 성능 최적화는 중요하다.
그러나 뭘 최적화해야 하는가? 웹사이트가 빠르다는 것은 무슨 의미일까? 내가 어떤 부분을 바꿨는데 사이트가 더 좋아졌는지 알아보려면 어떻게 해야 할까?
눈에 확 띌 정도로 차이난다면 상관 없겠지만, 차이가 미묘하다면 정량적인 지표를 통해 평가해야 할 것이다. 이런 지표에 대해 많은 연구가 이뤄졌다. web.dev 사이트에서 많은 정보를 찾을 수 있다.
lighthouse 라는 크롬 개발자 도구에 내장된 서비스를 사용하면 꽤 많은 성능 지표를 벤치마크할 수 있다. 자동으로 페이지를 새로고침하면서 여러 방면으로 점수를 내 준다. 여기서 띄워주는 성능 지표들이 무슨 의미인지 하나하나 알아보자.
Paint timing API 에서 제공. 페이지로 이동한 시각부터 첫 번째 픽셀이 화면에 그려지기까지 사이의 시간을 나타낸다. 이 때 첫 번째 픽셀은 페이지에 처음 들어갔을 때와 시각적으로 조금이라도 다른 경우만을 말한다. FP를 통해 사용자는 페이지에 접속하고 뭔가 반응했다는 것을 알 수 있다.
FMP는 페이지에서 가장 큰 레이아웃 변화와 웹 폰트 로드 이후 첫 번째 랜더링까지의 시간을 말한다. FMP는 재현성이 떨어지며 브라우저별로 매우 다른 결과를 보일 수 있다. 이 수치는 Lighthouse 6.0 부터 지원 중단했으며 LargestContentfulPaint API (LCP)를 사용하기를 권장하고 있다.
페이지가 로드되기 시작한 시점부터 가장 큰 텍스트 블록 또는 이미지 요소가 렌더링될 때까지의 시간을 측정한다. 사용자가 감지하는 로드 속도를 측정할 수 있는 중요한 메트릭이다. 좋은 사용자 경험을 위해 LCP는 2.5초 이하여야 하며, 75번째 백분위수를 측정하는 것이 바람직하다.
브라우저가 처음 컨텐츠 요소를 랜더링하는 데 걸리는 시간을 말한다. 컨텐츠는 텍스트, 이미지, 공백이 아닌 canvas 나 svg 등을 말한다. 유저가 처음으로 컨텐츠를 소비하기 시작하는 시간이다. 주요 컨텐츠 로드 시점을 측정하는 LCP와 달리 페이지의 일부라도 로딩이 끝나는 시간을 측정하는 지표이다.
우수한 사용자 경험을 제공하려면 FCP는 1.8초 이하여야 한다. 자바스크립트에서 Paint Timing API를 이용해 측정할 수 있다. 하지만 실제로 FCP를 계산할 때에는 백그라운드 탭 여부, 캐시 여부, iframe 에서의 랜더링 등에 따라 미묘한 차이가 발생할 수 있다. 따라서 지표를 더 간단하게 측정하려면 web-vitals 라이브러리를 사용하는 것을 추천한다.
FCP를 최적화하기 위한 방법으로 렌더링 차단 리소스 제거, CSS 축소, 핵심 요청 사전 로드, 캐시 활용, 요청 깊이 최소화 등이 있다.
<link rel="preconnect">
또는 <link rel="preload">
등으로 리소스 힌트를 추가하면 사용자 경험을 향상시킬 수 있다. <link rel="dns-prefetch">
는 dns 조회만 사전 처리하지만 브라우저 지원이 광범위하므로 좋은 대체 수단이다.페이지가 로드되기 시작한 시점부터 주요 하위 리소스가 로드된 후 사용자 입력에 안정적으로 응답할 수 있게 되기까지의 시간이다.
웹 페이지의 성능 추적을 기반으로 TTI를 계산하려면 다음 단계를 따른다.
요약하자면 FCP 이후 메인 스레드를 오래 블로킹하는 작업이 모두 끝나기까지의 시간이다.
SSR과 같은 기술을 사용하면 표시 속도는 빨라지지만 TTI가 희생될 수 있다. 이 경우 화면은 출력되지만 반응하지 않기 때문에, 사용자는 페이지의 응답 속도가 느리다고 생각하거나 고장났다고 생각할 수 있다. 이를 피하기 위해서는 FCP와 TTI 사이 간격을 최소화해야 한다. 또한 출력 속도와 반응 속도 간 차이가 있을 경우 시각적 요소를 통해 분명히 알려주어야 한다. 일반적으로 TTI는 5초 이하여야 한다.
사용자가 링크를 클릭하거나, 버튼을 탭하는 등 처음 상호작용할 때부터 이에 대한 이벤트 핸들러 처리를 시작하기까지의 걸리는 시간이다. 핸들러 처리 종료 시점이 아니라 시작 시점을 측정하는 이유는 비동기 이벤트 핸들러 등에서도 일관된 수치를 측정하기 위해서이다.
좋은 경험을 제공하려면 100밀리초 이하여야 하며, 75번째 백분위수를 측정한다. FID는 유저 시나리오에 따라 다르며, 사용자가 있어야 측정 가능하므로 자동 벤치마크에서는 TBT를 대신 측정한다. TBT는 FID와 밀접한 연관이 있다.
FCP와 TTI사이에서 메인 스레드가 입력을 막을 만큼 오래 차단되었던 시간의 합이다. FCP와 TTI 사이에서 긴 작업(50ms 를 초과하는 작업) 시간의 합을 측정한다. TBT는 긴 작업으로 인해 사이트가 상호작용 불가능해졌던 때의 심각성을 수량화하기 때문에 TTI와 같이 보기 좋은 메트릭이다. 좋은 사용자 경험을 위해 모바일 환경에서 300밀리초 이하로 되도록 유지해야 한다.
어떤 버튼을 클릭하려고 했는데 갑자기 광고가 뜨는 등으로 레이아웃이 바뀌어서 잘못된 요소를 클릭한 적이 있을 것이다. 이렇게 레이아웃이 갑자기 바뀌는 경우를 레이아웃 이동(Layout Shift)이라 한다.
CLS는 사용자가 예상하지 못한 레이아웃 이동을 경험하는 빈도를 측정한 것으로, 시각적 안정성을 측정할 때 중요한 사용자 중심 메트릭이다. CLS는 매 레이아웃 이동에 대해 점수를 매긴 후, 페이지의 전체 수명 동안 발생하는 모든 예기치 않은 레이아웃 이동에 대한 가장 큰 레이아웃 이동 점수 버스트로 정의한다. 우수한 사용자 경험을 위해 0.1 이하여야 한다. Layout Instability API를 통해 정의된다.