- Published on
2025.06.13
[리액트 딥다이브] - 12. 모든 웹 개발자가 관심을 가져야 할 핵심 웹 지표
12.1. 웹사이트와 성능
웹사이트의 성능과 사용자 경험 사이의 상관관계(주소)
- 1초 내로 로딩되는 사이트는 5초 내로 로딩되는 사이트보다 전자상거래 전환율이 2.5배 더 높음
- 0-5초 범위에서, 1초 로딩이 늦어질수록 전환율은 4.42%씩 떨어짐
- 페이지 로드 시간이 0-2초 사이인 페이지에서 가장 높은 전환율을 달성할 수 있음
웹사이트의 성능을 측정하기 위해 구글은 핵심 웹 지표(Core Web Vital)라고 하는 몇 가지 핵심 요소에 대한 지표를 제시하고 있음.
12.2. 핵심 웹 지표란?
구글이 핵심 웹 지표로 꼽는 지표
- 최대 콘텐츠풀 페인트(LCP: Largest Contentful Paint)
- 최초 입력 지연(FID: First Input Delay)
- 누적 레이아웃 이동(CLS: Cumulative Layout Shift)
다음 두 지표는 핵심은 아니지만 특정 문제를 진단하는 데 사용될 수 있음
- 최초 바이트까지의 시간(TTFB: Time To First Byte)
- 최초 콘텐츠풀 시간(FCP: First Contentful Paint)
12.3. 최대 콘텐츠풀 페인트(LCP)
12.3.1. 정의
페이지가 처음으로 로드를 시작한 시점부터 뷰포트 내부에서 가장 큰 이미지 또는 텍스트를 렌더링하는 데 걸리는 시간
뷰포트 내부에서 '큰 이미지와 텍스트'는 다음과 같이 정의되어 있음
<img>
<svg>
내부의<image>
- poster 속성을 사용하는
<video>
- url()을 통해 불러온 배경 이미지가 있는 요소
- 텍스트와 같이 인라인 텍스트 요소를 포함하고 있는 블록 레벨 요소
LCP란 뷰포트 내부에서 가장 큰 영역을 차지하는 요소가 렌더링되는 데 얼마나 걸리는지를 측정하는 지표로, 실제 크기가 커도 뷰포트 영여 밖에 넘치는 요소가 있다면 해당 영역의 크기는 고려되지 않음. 오로지 뷰포트 영역만 고려한다.
12.3.2. 의미
개발자가 생각하는 페이지 로딩 시간과 사용자가 체감하는 페이지 로딩 시간에는 차이가 있음.
개발자가 떠올리는 DOMContentLoaded 이벤트가 호출되는 시간은 HTML 문서를 완전히 불러오고 파싱했을 때 발생하는 이벤트로, 스타일시트, 이미지, 하위 프레임의 로딩은 기다리지 않음.
사용자가 페이지 로딩을 체감하기 위해 페이지가 완전히 로딩될 필요는 없음. 사용자에게 노출되는 부분(뷰포트)만 로딩되어 있으면 페이지 로딩이 완료되었다고 느낌. 그래서 페이지의 정보를 화면에 전달하는 속도를 객관적으로 판단하기 위한 지표로 만들어진 것이 LCP
12.3.4. 기준 점수
12.4. 최초 입력 지연(FID)
FID는 공식적으로 지원 종료 및 다음 페인트에 대한 상호작용(INP)이 핵심 웹 지표로 변경됨
다음 페인트에 대한 상호작용 (INP)
Chrome에서 최초 입력 지연 지원 종료
Core Web Vitals에 INP 도입
Next Paint와의 상호작용이 공식적으로 Core Web Vital이 되었습니다
12.5. 누적 레이아웃 이동(CLS)
12.5.1. 정의
페이지의 생명주기 동안 발생하는 예기치 않은 이동에 대한 지표를 계산하는 것.
12.5.2. 의미
과거와 달리, 렌더링이 끝난 이후 실행하는 useEffect처럼 클라이언트에서 처리해야 하는 작업이 늘어남. useEffect가 UI의 레이아웃을 변경하면 사용자가 보고 있던 콘텐츠의 위치가 바뀌어 상호작용에 실패하는 등, 누적 레이아웃 이동에 부정적.
CLS도 뷰포트 내의 요소에 대해서만 측정하며 사용자 액션으로 인한 레이아웃 이동은 점수에 포함되지 않음.
점수를 계산할 때 포함되는 내용은 다음과 같다.
- 영향분율: 레이아웃 이동이 발생한 요소의 전체 높이와 뷰포트 높이의 비율
- 거리분율: 레이아웃 이동이 발생한 요소가 뷰포트 대비 얼마나 이동했는지를 의미
12.5.3. 예제
페이지 가운데의 배너가 노출되지 않다가 이후 노출되는 경우, useEffect 등으로 배너의 노출 여부를 제어하는 것을 짐작해볼 수 있다.
갑자기 배너의 크기만큼 콘텐츠가 밀리면, 사용자는 부정적인 경험을 하게 된다. 즉 누적 레이아웃 이동으로 인해 불편을 겪는다.
유튜브의 경우, 로딩 상태임을 보여주는 스켈레톤 UI를 추가해 대략적인 페이지 레이아웃을 고정시켰다가 영상 썸네일로 교체해 레이아웃 이동을 최소화 함.
12.5.4. 기준 점수
12.5.5. 개선 방안
삽입이 예상되는 요소를 위한 추가적인 공간 확보
- useLayoutEffect를 사용하는 방법이 있지만, 누적 레이아웃 이동을 막으려다가 다른 모든 작업에 악영향을 끼칠 수 있음.
- 스켈레톤 UI처럼 동적으로 뜰 것이 예상되는 공간을 미리 확보해 두는 것도 좋은 방법.
- 가장 좋은 방법은 서버 사이드 렌더링
폰트 로딩 최적화
폰트도 레이아웃 이동을 일으킴.
적절한 이미지 크기 설정
img {
width: 100%;
height: auto;
}
이 경우 누적 레이아웃 이동이 커짐. 이미지가 완전히 다운로드되기 전까지는 높이를 알 수 없기 때문. height: auto
는 반응형 웹사이트에 최적화할 수 있는 기법이지만, 이미지의 높이를 명확히 알지 못해 레이아웃 이동이 크게 발생한다는 단점이 있음.
이를 해결하기 위해 다음과 같은 방법이 있다.
- width, height 지정: width: 100%; height: auto;와 함께 width, height를 원하는 비율로 지정하면 브라우저가 적절한 가로세로 비율을 계산해 면적을 할당해 둠
- srcset 속성 사용: 반응형 이미지를 사용하고 싶다면 srcset을 사용해 비율이 같지만 크기가 다른 여러 개의 이미지를 상황에 맞게 사용할수 있도록 한다
12.5.6. 핵심 웹 지표는 아니지만 성능 확인에 중요한 지표들
최초 바이트까지의 시간(Time To First Byte, TTFB)
브라우저가 웹페이지의 첫 번째 바이트를 수신하는 데 걸리는 시간, 페이지를 요청했을 때 요청이 완전히 완료되는 데 걸리는 시간이 아니라 최초의 응답이 오는 바이트까지가 얼마나 걸리는지를 측정하는 지표.
특히 서버 사이드 렌더링을 하고 있는 애플리케이션에서 주의 깊게 봐야 한다.
최초 콘텐츠풀 페인트(First Contentful Paint, FCP)
페이지가 로드되기 시작한 시점부터 페이지 콘텐츠의 일부가 화면에 렌더링될 때까지의 시간을 측정, 웹사이트에 접속한 순간부터 페이지에 요소(텍스트, 이미지, svg 등)가 나타나기 시작한 시점까지의 시간을 의미.
책에서 소개된 내용 이외에, FID를 대체한 INP에 대해서도 알아보면 좋을 것 같다.