웹 성능 최적화 핵심 전략
Core Web Vitals부터 실전 최적화 기법까지. 사용자 경험을 향상시키는 성능 최적화 방법을 알아봅니다.
웹 성능은 사용자 경험과 비즈니스 성과에 직접적인 영향을 미칩니다. 로딩이 1초 늦어지면 전환율이 7% 감소한다는 연구 결과도 있습니다. 성능 최적화는 선택이 아닌 필수입니다.
Core Web Vitals
Google이 정의한 핵심 성능 지표입니다. 검색 순위에도 영향을 미칩니다.
LCP (Largest Contentful Paint)
페이지에서 가장 큰 콘텐츠가 화면에 표시되는 시간입니다. 2.5초 이내가 좋습니다.
개선 방법은 다음과 같습니다.
- 서버 응답 시간 단축
- 렌더 블로킹 리소스 제거
- 이미지 최적화
- CDN 사용
FID (First Input Delay)
사용자가 첫 상호작용을 했을 때 브라우저가 응답하기까지 걸리는 시간입니다. 100ms 이내가 좋습니다.
개선 방법은 다음과 같습니다.
- JavaScript 실행 시간 단축
- 긴 작업을 작은 단위로 분할
- 메인 스레드 부담 줄이기
CLS (Cumulative Layout Shift)
페이지 로딩 중 레이아웃이 얼마나 이동하는지 측정합니다. 0.1 이하가 좋습니다.
개선 방법은 다음과 같습니다.
- 이미지와 비디오에 크기 지정
- 광고 영역 미리 확보
- 웹폰트 로딩 최적화
이미지 최적화
이미지는 대부분의 웹사이트에서 가장 큰 용량을 차지합니다.
적절한 포맷 선택
<!-- 모던 포맷 우선, 폴백 제공 -->
<picture>
<source srcset="image.avif" type="image/avif" />
<source srcset="image.webp" type="image/webp" />
<img src="image.jpg" alt="설명" />
</picture>
AVIF는 JPEG 대비 50% 이상 용량을 줄일 수 있습니다. WebP도 30% 정도 절약됩니다.
반응형 이미지
<img
src="image-800.jpg"
srcset="
image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w
"
sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
alt="설명"
/>
화면 크기에 맞는 이미지를 로드합니다. 모바일에서 불필요하게 큰 이미지를 다운로드하지 않습니다.
지연 로딩
<img src="image.jpg" alt="설명" loading="lazy" />
뷰포트에 들어올 때까지 이미지 로딩을 지연합니다. 초기 로딩 속도가 빨라집니다.
JavaScript 최적화
코드 스플리팅
// 동적 import로 필요할 때 로드
const Modal = lazy(() => import('./Modal'));
function App() {
return (
<Suspense fallback={<Loading />}>
{showModal && <Modal />}
</Suspense>
);
}
초기 번들 크기를 줄이고, 필요한 코드만 로드합니다.
Tree Shaking
사용하지 않는 코드를 번들에서 제거합니다. ES 모듈 문법을 사용해야 합니다.
// 나쁜 예 - 전체 라이브러리 포함
import _ from 'lodash';
// 좋은 예 - 필요한 함수만 포함
import { debounce } from 'lodash-es';
번들 분석
# Next.js
npx @next/bundle-analyzer
# Webpack
npx webpack-bundle-analyzer stats.json
번들 크기를 시각화해서 어떤 라이브러리가 용량을 차지하는지 파악합니다.
캐싱 전략
HTTP 캐싱
# 정적 자산 (이미지, JS, CSS)
Cache-Control: public, max-age=31536000, immutable
# HTML
Cache-Control: no-cache
# API 응답
Cache-Control: private, max-age=0, must-revalidate
정적 자산은 장기 캐싱하고, 파일명에 해시를 포함해서 버전을 관리합니다.
서비스 워커
// 오프라인 지원 및 캐싱
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
폰트 최적화
필요한 글자만 포함
@font-face {
font-family: 'MyFont';
src: url('font.woff2') format('woff2');
unicode-range: U+AC00-D7AF; /* 한글만 */
}
폰트 로딩 전략
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin />
<style>
@font-face {
font-family: 'MyFont';
src: url('font.woff2') format('woff2');
font-display: swap; /* 폰트 로딩 중 시스템 폰트 표시 */
}
</style>
성능 측정 도구
Lighthouse
Chrome DevTools에 내장되어 있습니다. 성능, 접근성, SEO 등을 종합적으로 측정합니다.
WebPageTest
실제 네트워크 환경에서 테스트합니다. 여러 지역에서 테스트할 수 있어 유용합니다.
Chrome DevTools Performance 탭
JavaScript 실행 시간, 레이아웃, 페인트 등을 상세히 분석합니다.
마무리
성능 최적화는 한 번에 끝나는 작업이 아닙니다. 지속적으로 측정하고 개선해야 합니다.
가장 효과적인 전략은 이미지 최적화와 코드 스플리팅입니다. 이 두 가지만 제대로 해도 대부분의 사이트에서 큰 개선을 볼 수 있습니다.
성능 예산을 설정하고, CI/CD 파이프라인에서 자동으로 체크하는 것을 추천합니다.