Ch 04. 성능 최적화 — 번들 분석·이미지·캐싱
사이트가 잘 만들어져도 느리면 사용자가 떠납니다. 구글 PageSpeed Insights 점수가 낮으면 검색 순위도 떨어집니다. 배포 전에 번들 크기, 이미지, HTTP 캐싱을 점검하는 습관을 들이면 체감 속도가 크게 달라집니다.
번들 분석
어떤 패키지가 자바스크립트 번들을 크게 만드는지 시각적으로 확인할 수 있습니다.
npm install -D nuxt-bundle-analyzer
nuxt.config.ts에 모듈을 추가합니다.
export default defineNuxtConfig({ modules: ['nuxt-bundle-analyzer']})
npm run build를 실행하면 빌드가 끝난 뒤 브라우저에 트리맵 형태의 분석 리포트가 열립니다. 예상치 못하게 큰 라이브러리를 발견하면 더 가벼운 대안으로 교체하거나, 해당 기능을 서버사이드로 이동하는 방법을 고려합니다.
NuxtImage로 이미지 최적화
이미지는 웹 페이지 용량의 절반 이상을 차지하는 경우가 많습니다. @nuxt/image는 요청 시점에 이미지를 WebP나 AVIF로 변환하고, 화면 크기에 맞게 리사이징해줍니다.
npm install @nuxt/image
nuxt.config.ts의 modules에 @nuxt/image를 추가한 뒤 컴포넌트에서 사용합니다.
<NuxtImg src="/uploads/photo.jpg" width="800" format="webp" />
<img> 태그 대신 <NuxtImg>를 사용하는 것만으로 이미지 최적화가 적용됩니다. lazy 속성을 추가하면 뷰포트에 진입할 때만 로딩하는 지연 로딩도 자동으로 처리됩니다.
HTTP 캐싱과 routeRules
정적 자산은 브라우저가 캐시할 수 있도록 캐시 헤더를 설정합니다. nuxt.config.ts의 routeRules로 경로별 응답 헤더를 제어할 수 있습니다.
export default defineNuxtConfig({ routeRules: { '/uploads/**': { headers: { 'cache-control': 'public, max-age=31536000, immutable' } }, '/api/**': { headers: { 'cache-control': 'no-store' } } }})
업로드 이미지는 1년 캐시, API 응답은 캐시 없음으로 설정하는 예시입니다.
Nitro 압축
Nitro는 서버에서 응답을 Gzip 또는 Brotli로 압축해서 전송할 수 있습니다.
export default defineNuxtConfig({ nitro: { compressPublicAssets: true }})
이 옵션 하나로 JavaScript와 CSS 파일의 전송 크기를 60~70% 줄일 수 있습니다. 설정 비용 대비 효과가 가장 큰 최적화 중 하나입니다.