(3/6) 홈페이지 스트레스 테스트 — 프론트엔드 성능과 코어 웹 바이탈
- 무엇을·왜·어떤 지표로 재는가 — 테스트 종류와 목표 지표
- k6 로 부하·스파이크·소크 돌리기 — 실전 부하 시나리오
- 프론트엔드 성능 — 코어 웹 바이탈과 렌더링 스트레스 ← 지금 글
- 백엔드·DB 병목 찾기 — 모니터링과 프로파일링
- 복원력 테스트 — 카오스 엔지니어링과 장애 주입
- 보안·가용성 스트레스 — Rate Limit·DDoS·종합 체크리스트
Summary
2편의 k6 는 서버가 응답을 돌려주는 속도를 쟀어요. 그런데 사용자가 “이 사이트 느리다”고 느끼는 건 서버 응답만이 아닙니다. 응답을 받은 브라우저가 화면을 다 그리고, 눌렀을 때 반응하기까지의 전 과정이에요. 서버가 50ms 만에 HTML 을 줘도, 그 안에 무거운 이미지와 자바스크립트가 잔뜩 들어 있으면 화면은 5초 뒤에 뜹니다.
이번 편은 이 프론트엔드 층을 잽니다. 구글이 표준으로 정한 코어 웹 바이탈이 무엇인지, Lighthouse 와 WebPageTest 로 어떻게 측정하는지, 그리고 저사양 기기·느린 네트워크로 프론트엔드에 스트레스를 거는 법까지 다뤄요.
💡 이 글에서 다루는 것
- 왜 서버 속도와 체감 속도가 다른가
- 코어 웹 바이탈 — LCP·INP·CLS 세 지표의 의미
- Lighthouse 로 점수 내고 병목 찾기
- WebPageTest 로 폭포수(waterfall) 읽기
- 저사양 기기·3G 로 프론트엔드 스트레스 걸기
1. 서버는 빠른데 왜 느릴까
k6 결과가 아무리 좋아도 사용자가 느리다고 느끼는 경우가 있어요. 브라우저가 HTML 을 받은 다음에 하는 일이 많기 때문입니다. 대략 이런 순서로 일해요.
1. HTML 받기 ← 여기까지가 k6 가 재는 구간
2. CSS·JS·이미지 요청 ← 딸린 리소스 수십 개 추가 다운로드
3. 자바스크립트 실행 ← 무거우면 여기서 화면이 멈춤(블로킹)
4. 화면 그리기(렌더링)
5. 사용자 입력에 반응
즉 k6 가 재는 건 1번까지고, 사용자 체감은 5번까지입니다. 프론트엔드가 무거우면 서버가 아무리 빨라도 2~4번에서 몇 초가 날아가요. 그래서 프론트엔드는 실제 브라우저로 재야 합니다. HTTP 요청만 보내는 k6 로는 이 층이 안 잡혀요.
2. 코어 웹 바이탈 — 세 개의 숫자
구글은 사용자 체감 속도를 세 가지 지표로 표준화했어요. 이걸 코어 웹 바이탈(Core Web Vitals) 이라고 부르고, 검색 순위에도 반영됩니다. 세 지표가 각각 다른 순간을 잽니다.
| 지표 | 정식 이름 | 재는 것 | 좋음 기준 |
|---|---|---|---|
| LCP | Largest Contentful Paint | 가장 큰 콘텐츠가 뜨기까지의 시간 |
2.5초 이하 |
| INP | Interaction to Next Paint | 클릭·입력에 반응하는 속도 |
200ms 이하 |
| CLS | Cumulative Layout Shift | 화면이 갑자기 밀리는 정도 |
0.1 이하 |
각각을 사용자 언어로 풀면 이래요.
- LCP 는 “언제 화면이 다 뜬 것처럼 보이나”. 히어로 이미지나 큰 제목이 뜨는 순간이에요. 무거운 이미지, 느린 폰트가 주범입니다.
- INP 는 “버튼을 눌렀을 때 얼마나 빨리 반응하나”. 자바스크립트가 무거워서 메인 스레드가 막혀 있으면, 눌러도 한참 있다 반응해요. (예전 FID 지표를 2024년에 대체한 지표입니다.)
- CLS 는 “글을 읽으려는데 광고·이미지가 늦게 떠서 화면이 밀리는” 그 짜증. 이미지 크기를 미리 지정 안 하면 잘 터져요.
💡 이 셋은 서로 트레이드오프가 있어요. 예를 들어 자바스크립트를 몰아서 한 번에 로드하면 LCP 는 빨라지지만 INP 가 나빠집니다. 그래서 하나만 최적화하지 말고 셋을 함께 봐야 해요.
3. Lighthouse — 가장 빠른 진단
가장 손쉬운 도구는 크롬에 내장된 Lighthouse 예요. 크롬 개발자도구(F12) → Lighthouse 탭에서 바로 돌릴 수 있습니다. 하지만 자동화·반복 측정에는 명령줄 버전이 편해요.
npm install -g lighthouse
특정 페이지를 측정하고 리포트를 뽑습니다.
lighthouse https://example.com --output=json --output-path=./report.json --only-categories=performance
Lighthouse 는 성능을 0~100 점으로 요약해주고, 무엇 때문에 점수가 깎였는지 항목별로 알려줘요. 결과 JSON 에서 핵심만 뽑아보면 이런 값들이 들어 있어요.
Performance score: 72
Largest Contentful Paint: 3.4 s ← 기준(2.5s) 초과, 개선 필요
Total Blocking Time: 480 ms ← JS 가 메인 스레드를 오래 막음
Cumulative Layout Shift: 0.02 ← 양호
Speed Index: 2.9 s
개선 제안:
- 오프스크린 이미지 지연 로딩 → 예상 절감 1.2s
- 사용하지 않는 자바스크립트 제거 → 예상 절감 0.6s
- 차세대 이미지 포맷(WebP/AVIF) 사용 → 예상 절감 0.9s
여기서 중요한 건 점수 자체가 아니라 개선 제안입니다. Lighthouse 는 “이미지가 커서 1.2초 손해, 안 쓰는 JS 때문에 0.6초 손해”처럼 구체적으로 짚어줘요. 이걸 큰 것부터 처리하면 됩니다.
⚠️ Lighthouse 점수는 측정할 때마다 조금씩 흔들려요. 네트워크 상태, 백그라운드 프로세스에 영향받거든요. 한 번의 점수에 일희일비하지 말고 여러 번 돌려 중앙값을 보세요. CI 에 넣을 때도 “3회 측정 후 중앙값이 기준 미만이면 실패”처럼 잡는 게 안정적입니다.
4. WebPageTest — 폭포수로 병목 보기
Lighthouse 가 “점수와 제안”이라면, WebPageTest 는 “리소스 하나하나가 언제 로드됐는지”를 폭포수(waterfall) 그래프로 보여줘요. 어느 파일이 병목인지 눈으로 짚을 때 최고입니다.
폭포수 그래프를 읽는 핵심 포인트를 정리하면 이래요.
- 긴 막대 — 다운로드가 오래 걸린 리소스. 큰 이미지·폰트·번들 JS 가 후보.
- 계단식 지연 — A 가 끝나야 B 가 시작되는 직렬 체인. 병렬로 바꿀 수 있으면 큰 이득.
- 뒤늦게 시작하는 요청 — 자바스크립트가 실행된 뒤에야 요청되는 리소스. 미리 불러오면(preload) 당길 수 있음.
- 첫 바이트까지의 시간(TTFB) — 여기가 길면 프론트가 아니라 서버 문제. 4편으로 넘어갈 신호예요.
WebPageTest 는 실제 여러 지역·실기기에서 측정할 수 있어서, “서울에선 빠른데 미국에선 느린” 같은 지역 편차도 잡아냅니다. CDN 이 제대로 붙었는지 검증할 때 특히 유용해요.
5. 프론트엔드에 스트레스 걸기
여기까지가 “측정”이라면, 이제 프론트엔드를 일부러 가혹한 조건에 넣어 보는 스트레스 단계예요. 개발자 장비는 대부분 최신 고사양 + 빠른 인터넷이라, 그 환경에서만 테스트하면 실제 사용자 경험을 놓칩니다.
저사양 기기 흉내 (CPU 스로틀링)
크롬 개발자도구는 CPU 를 일부러 느리게 만들 수 있어요. Performance 탭에서 “CPU: 4x slowdown” 을 켜면 4배 느린 기기를 흉내 냅니다. 저가 안드로이드폰에서 자바스크립트가 얼마나 버벅이는지 여기서 드러나요. INP 가 이 조건에서 급격히 나빠진다면, 자바스크립트가 너무 무겁다는 신호입니다.
느린 네트워크 흉내 (네트워크 스로틀링)
같은 개발자도구 Network 탭에서 “Slow 3G” 를 선택하면 느린 모바일 네트워크를 흉내 냅니다. 이 조건에서 페이지가 뜨는 데 10초가 걸린다면, 리소스가 너무 많거나 크다는 뜻이에요. Lighthouse 도 기본적으로 “모바일 + 느린 네트워크” 조건으로 측정하는 이유가 이겁니다.
자동화로 반복 측정
명령줄 Lighthouse 에 조건을 걸어 스크립트로 반복하면, 배포할 때마다 성능이 나빠지지 않았는지 감시할 수 있어요.
# 모바일 + 4배 CPU 스로틀 조건으로 측정, HTML 리포트로 저장
lighthouse https://example.com \
--preset=perf \
--throttling.cpuSlowdownMultiplier=4 \
--form-factor=mobile \
--output=html --output-path=./mobile-report.html
🚨 성능은 방치하면 반드시 나빠집니다(성능 퇴행). 이미지 하나, 라이브러리 하나가 슬금슬금 늘면서 어느 날 갑자기 느려져요. 그래서 프론트엔드 성능은 한 번 재고 끝이 아니라, 배포 파이프라인에 넣어 매번 자동으로 감시하는 게 정석입니다. “LCP 가 2.5초를 넘으면 배포 실패”처럼요.
6. 정리
- 서버 응답 속도(k6)와 체감 속도(브라우저 렌더링) 는 다른 층이다
- 코어 웹 바이탈 = LCP(뜨는 속도) · INP(반응 속도) · CLS(밀림)
- Lighthouse 로 점수와 개선 제안을, WebPageTest 로 폭포수 병목을 본다
- CPU 스로틀·느린 3G 로 저사양 사용자 환경을 흉내 내 스트레스
- 성능은 퇴행하니 배포 파이프라인에서 자동 감시
프론트엔드에서 병목을 찾다가 TTFB(첫 바이트까지의 시간)가 길게 나오면, 그건 프론트가 아니라 서버 안쪽 문제예요. 다음 편에서는 그 안쪽 — 백엔드와 데이터베이스 — 로 들어가서, 부하를 걸었을 때 어느 쿼리·어느 커넥션이 병목인지 찾는 법을 다룰게요.
일단 오늘은 여기까지….. 다음 글에서는 백엔드·DB 병목을 모니터링으로 찾는 법을 정리해볼게요.
← 이전 글: (2/6) 홈페이지 스트레스 테스트 — k6 로 부하·스파이크·소크 돌리기 | 다음 글 →: (4/6) 홈페이지 스트레스 테스트 — 백엔드·DB 병목 찾기