한 줄 정의
웹 애플리케이션의 사용자 체감 성능을 객관적으로 측정하기 위한 지표들입니다.
쉽게 말하면
“이 페이지 느려요”라는 막연한 불만을 “FCP가 3초니까 느린 겁니다”처럼 숫자로 바꿔주는 도구입니다. 무엇이 느린지, 어디서 병목이 생기는지를 구분해서 측정할 수 있어야 개선도 가능합니다.
왜 중요한가?
“성능”이라는 단어 하나로는 무엇을 측정해야 하는지 알 수 없습니다. 페이지 로딩이 느린 건지, 인터랙션 반응이 느린 건지, 리소스가 너무 큰 건지에 따라 원인과 해결책이 완전히 다릅니다.
이 지표들은 각각 성능의 다른 측면을 포착하므로, 아키텍트와 개발자가 같은 언어로 성능을 논의 할 수 있게 해줍니다. Ch06 아키텍처 특성의 측정과 거버넌스에서 강조하는 “아키텍처 특성의 객관적 측정”이 바로 이런 지표들을 통해 실현됩니다.
핵심 내용
최초 콘텐츠 렌더링(First Contentful Paint, FCP)
FCP 는 페이지가 로드되기 시작한 시점부터 텍스트, 이미지, 캔버스 등 첫 번째 콘텐츠가 화면에 렌더링되는 시점 까지의 시간을 측정합니다. Google의 Core Web Vitals 중 하나이며, 사용자가 “뭔가 나오기 시작했다”고 느끼는 순간을 포착하는 지표입니다.
| 등급 | 시간 |
|---|---|
| Good | 1.8초 이하 |
| Needs Improvement | 1.8 ~ 3.0초 |
| Poor | 3.0초 초과 |
FCP에 영향을 주는 요소
- 서버 응답 시간(TTFB: Time to First Byte)
- 렌더링을 차단하는 CSS/JS 리소스
- 웹 폰트 로딩 지연
- CDN 사용 여부
FCP vs LCP
FCP는 “첫 번째 콘텐츠”이고, LCP(Largest Contentful Paint) 는 “가장 큰 콘텐츠”가 렌더링되는 시점입니다. FCP가 빠르더라도 메인 이미지나 텍스트 블록(LCP)이 늦게 뜨면 사용자 체감은 여전히 느립니다. 현재 Core Web Vitals에서는 LCP를 더 중요한 지표로 다루고 있습니다.
최초 CPU 유휴 상태(First CPU Idle)
First CPU Idle 은 페이지의 메인 스레드가 사용자 입력을 처리할 수 있을 만큼 충분히 여유로워지는 최초 시점 을 측정합니다. 페이지가 시각적으로 렌더링되었더라도 JS가 메인 스레드를 점유하고 있으면 버튼 클릭이나 스크롤에 반응하지 않는데, 이 지표는 그 “반응 가능 시점”을 잡아냅니다.
Deprecated 상태
이 지표는 현재 Lighthouse 6.0부터 deprecated 되었으며, TTI(Time to Interactive) 와 TBT(Total Blocking Time) 로 대체되었습니다.
왜 deprecated 되었는가?
First CPU Idle은 “최소한의 인터랙션 가능 시점”, TTI는 “완전한 인터랙션 가능 시점”인데, 실제로 두 값이 거의 비슷하게 나오는 경우가 많아 별도 지표로 유지할 실익이 없었습니다. 또한 페이지 로드 과정에서 작은 변화에도 수치가 크게 흔들려(noisy) 성능 개선의 근거로 쓰기 어려웠습니다. TTI + TBT 조합이 사용자 체감을 더 정확하고 안정적으로 측정합니다.
| 지표 | 측정 대상 |
|---|---|
| First CPU Idle (deprecated) | 최소한의 인터랙션이 가능한 시점 |
| TTI (Time to Interactive) | 페이지가 완전히 인터랙티브한 시점 (50ms 이내 응답 가능) |
| TBT (Total Blocking Time) | FCP ~ TTI 사이에서 메인 스레드가 50ms 이상 차단된 총 시간 |
TTI는 “완전히 반응 가능한 시점”이고, TBT는 “그 사이에 얼마나 막혀 있었는지”를 보여줍니다. 두 지표를 함께 보면 사용자가 체감하는 인터랙션 지연을 더 정확하게 파악할 수 있습니다.
K-가중치 예산(K-Weight Budget)
K-가중치 예산 은 웹 페이지에 포함되는 모든 리소스(JS, CSS, 이미지, 폰트 등)의 총 전송 크기를 KB 단위로 제한 하는 성능 예산 기법입니다.
왜 “크기”를 제한하는가?
특히 모바일 기기의 저대역폭 환경에서는 네트워크로 한 번에 전송할 수 있는 바이트 양에 물리적 한계가 있습니다. 리소스 크기가 커지면 다운로드 시간이 길어지고, 파싱·실행 시간도 함께 늘어납니다. 크기를 제한하면 자연스럽게 로딩 성능이 개선됩니다.
적용 방식
페이지 단위로 리소스 총량의 상한선을 정하고, CI/CD 파이프라인에서 빌드 시 체크합니다.
| 리소스 유형 | 예산 예시 |
|---|---|
| JavaScript | 200KB 이하 |
| CSS | 50KB 이하 |
| 이미지 | 500KB 이하 |
| 폰트 | 100KB 이하 |
| 합계 | 800KB 이하 |
이런 예산은 프로젝트마다 다르며, 타깃 사용자의 네트워크 환경과 디바이스 사양에 맞춰 설정합니다. webpack의 performance.maxAssetSize 설정이나 Lighthouse CI의 budget.json 같은 도구로 자동화할 수 있습니다.
정리
timeline title 페이지 로딩 타임라인에서 각 지표의 위치 요청 시작 : TTFB 첫 렌더링 : FCP 주요 콘텐츠 : LCP 인터랙션 가능 : TTI
| 지표 | 측정 관점 | 개선 방향 |
|---|---|---|
| FCP | 시각적 피드백 시작 | 서버 응답 최적화, 렌더 차단 리소스 제거 |
| TTI (구 First CPU Idle) | 인터랙션 가능 시점 | JS 번들 크기 축소, 코드 스플리팅 |
| K-weight budget | 리소스 총량 제한 | 불필요한 의존성 제거, 이미지 최적화, 트리 쉐이킹 |
내 생각
- K-weight budget은 특히 서드파티 라이브러리 관리 에 효과적입니다. “이 라이브러리 추가하면 예산 초과”라는 객관적 근거가 생기면 불필요한 의존성 추가를 막을 수 있습니다.
- 백엔드 관점에서는 FCP에 직접 영향을 주는 TTFB(Time to First Byte) 가 더 직접적인 관심사입니다. 서버 응답이 느리면 프론트엔드에서 아무리 최적화해도 FCP가 좋아지지 않습니다.
관련 개념
출처
- Google Developers, “First Contentful Paint”, web.dev
- Google Developers, “Time to Interactive”, web.dev