iBetter Books
수정

Ch 04. 성능 측정 — Lighthouse와 Core Web Vitals

배포했다고 끝이 아닙니다. 실제로 사용자에게 빠르게 느껴지는지 확인해야 합니다. 직접 체감하는 속도와 실제 측정값이 다를 수 있습니다. 개발자의 고사양 컴퓨터와 빠른 인터넷 환경은 일반 사용자와 다릅니다.

Lighthouse는 Google이 만든 성능 측정 도구입니다. Chrome에 내장되어 있어 별도 설치 없이 사용할 수 있습니다.

Lighthouse 사용법

  1. Chrome에서 측정할 페이지를 엽니다.
  2. F12를 눌러 개발자 도구를 엽니다.
  3. Lighthouse 탭을 클릭합니다.
  4. Analyze page load를 클릭합니다.

잠시 후 100점 만점의 네 가지 점수가 나타납니다.

  • Performance: 페이지 로딩 속도와 반응성
  • Accessibility: 장애인 접근성 (스크린 리더, 키보드 탐색 등)
  • Best Practices: 보안, HTTPS, 최신 API 사용 여부
  • SEO: 검색 엔진 최적화

Core Web Vitals — 세 가지 핵심 지표

Google이 2021년부터 검색 순위 요소로 반영하는 세 가지 지표입니다. Performance 점수의 핵심을 이룹니다.

LCP (Largest Contentful Paint) — 가장 큰 요소 로딩 시간

화면에서 가장 큰 요소(일반적으로 히어로 이미지, 큰 제목)가 보이는 데 걸리는 시간입니다.

점수 기준
좋음 2.5초 이하
개선 필요 2.5~4초
나쁨 4초 초과

LCP를 개선하는 방법입니다.

  • 히어로 이미지에 priority 속성을 추가합니다.
  • 서버에서 미리 렌더링합니다 (SSR, SSG).
  • 이미지를 WebP/AVIF 형식으로 제공합니다.

INP (Interaction to Next Paint) — 상호작용 응답성

사용자가 클릭, 탭, 키 입력 등을 했을 때 화면이 반응하는 속도입니다. (2024년 3월 FID를 대체했습니다.)

점수 기준
좋음 200ms 이하
개선 필요 200~500ms
나쁨 500ms 초과

INP를 개선하는 방법입니다.

  • 무거운 JavaScript 연산을 Web Worker로 분리합니다.
  • 불필요한 클라이언트 컴포넌트를 서버 컴포넌트로 전환합니다.
  • 이벤트 핸들러를 최적화합니다.

CLS (Cumulative Layout Shift) — 레이아웃 이동

페이지가 로드되는 동안 요소들이 얼마나 이동하는지를 측정합니다. 글을 읽다가 갑자기 버튼이 내려가서 엉뚱한 것을 누른 경험이 있다면 CLS가 높은 것입니다.

점수 기준
좋음 0.1 이하
개선 필요 0.1~0.25
나쁨 0.25 초과

CLS를 개선하는 방법입니다.

  • <Image> 컴포넌트에 width, height를 명시합니다.
  • 동적으로 추가되는 콘텐츠에 공간을 미리 확보합니다.
  • 웹 폰트 로딩 시 font-display: swap을 사용합니다.

Next.js가 자동으로 최적화하는 것들

Next.js를 사용하는 것만으로도 많은 최적화가 자동으로 이루어집니다.

이미지 최적화: next/image가 자동으로 WebP 변환, 지연 로딩, 크기 최적화를 처리합니다.

코드 분할: 각 페이지에 필요한 JavaScript만 로드합니다. 하나의 거대한 번들 대신, 페이지별로 작은 청크가 만들어집니다.

폰트 최적화: next/font를 사용하면 Google Fonts를 로컬로 호스팅해 외부 요청을 줄입니다.

// 파일: app/layout.tsximport { Inter } from "next/font/google";const inter = Inter({  subsets: ["latin"],  display: "swap",});export default function RootLayout({ children }: { children: React.ReactNode }) {  return (    <html lang="ko" className={inter.className}>      <body>{children}</body>    </html>  );}```text**스크립트 최적화**: `next/script`의 `strategy` 옵션으로 서드파티 스크립트 로딩을 제어합니다.```typescriptimport Script from "next/script";// 페이지 로딩 후에 실행<Script src="https://analytics.example.com/script.js" strategy="lazyOnload" />```text### 점수를 높이는 실용적인 팁1. **LCP 이미지에 priority 추가**: 화면 상단 이미지에 `priority` 속성을 붙입니다.2. **불필요한 "use client" 제거**: 클라이언트 컴포넌트가 많을수록 JavaScript 번들이 커집니다.3. **Suspense로 스트리밍**: 느린 데이터를 기다리는 동안 나머지 페이지를 먼저 보여줍니다.4. **캐싱 활용**: `unstable_cache`, `revalidateTag`로 불필요한 데이터 재조회를 줄입니다.5. **번들 분석**: `@next/bundle-analyzer`로 어떤 모듈이 번들을 크게 만드는지 확인합니다.```bashnpm install @next/bundle-analyzerANALYZE=true npm run build

다음 챕터에서는 배포 후 장애가 발생했을 때 대응하는 체크리스트를 정리합니다.