next/image priority 속성으로 LCP 최적화하기
Next.js Image 컴포넌트의 priority 속성을 활용하여 Largest Contentful Paint를 개선하는 방법을 알아봅니다.
next/image priority 속성으로 LCP 최적화하기
Introduction
Largest Contentful Paint(LCP)는 페이지 로딩 성능을 측정하는 Core Web Vitals 중 하나입니다. Next.js의 priority 속성을 사용하면 hero 이미지나 로고 같은 첫 화면 이미지를 빠르게 로드할 수 있습니다. 이 글에서는 priority 속성의 동작 원리와 최적화 전략을 다룹니다.
Environment
# 프로젝트 구조
my-app/
├── app/
│ ├── page.tsx
│ └── components/
│ └── Hero.tsx
├── public/
│ └── images/
│ ├── hero.jpg
│ └── logo.png
└── package.json
# 기술 스택
Next.js: 14.2.5
React: 18.3.1
Lighthouse: 11.0Problem
기본 Image 컴포넌트는 lazy loading을 적용하므로 LCP에 부정적 영향을 줄 수 있습니다:
// ❌ LCP 이미지에 lazy loading 적용
import Image from 'next/image';
export function Hero() {
return (
{/* 이 이미지도 lazy loading되어 지연 로드됨 */}
);
}# Lighthouse 결과
Largest Contentful Paint (LCP): 4.2s
- 이미지 로딩 지연이 주요 원인Analysis
priority 속성을 설정하면:
loading="lazy"대신loading="eager"적용<link rel="preload">태그 자동 생성- 브라우저가 이미지를 우선적으로 로드
Solution
1. 기본 priority 설정
// app/components/Hero.tsx
import Image from 'next/image';
export function Hero() {
return (
);
}2. 조건부 priority 설정
// app/components/DynamicHero.tsx
import Image from 'next/image';
interface DynamicHeroProps {
isAboveFold: boolean;
src: string;
alt: string;
}
export function DynamicHero({ isAboveFold, src, alt }: DynamicHeroProps) {
return (
);
}3. 복수 LCP 이미지 처리
// app/page.tsx
import Image from 'next/image';
export default function HomePage() {
return (
{/* 첫 번째 LCP 이미지 */}
{/* 두 번째 LCP 이미지 (슬라이드쇼 등) */}
{/* 일반 이미지는 lazy loading 유지 */}
);
}4. 뷰포트 기반 동적 priority
// hooks/useViewport.ts
'use client';
import { useState, useEffect } from 'react';
export function useViewport() {
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const checkMobile = () => {
setIsMobile(window.innerWidth < 768);
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
return { isMobile };
}// app/components/ResponsiveHero.tsx
'use client';
import Image from 'next/image';
import { useViewport } from '@/hooks/useViewport';
export function ResponsiveHero() {
const { isMobile } = useViewport();
return (
);
}5. priority 사용 시 주의사항
// ❌ 과도한 priority 사용 (성능 저하)
export function BadExample() {
return (
{/* 모든 이미지에 priority 설정 - 안 됨 */}
);
}
// ✅ 올바른 사용 (LCP 이미지만 priority)
export function GoodExample() {
return (
);
}6. 빌드 타임 이미지 최적화
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
// priority 이미지에 대한 추가 설정
minimumCacheTTL: 60 * 60 * 24 * 30, // 30일
// 기기별 크기 설정
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
// 이미지 포맷 설정
formats: ['image/avif', 'image/webp'],
},
};
module.exports = nextConfig;Lessons Learned
- LCP 이미지만 priority 적용: 페이지당 1-2개의 LCP 이미지만 priority 설정
- above-the-fold 판단: 뷰포트 위에 보이는 이미지만 priority 적용
- sizes 속성 병행:
priority와sizes를 함께 사용하여 반응형 이미지 최적화 - 성능 측정: Lighthouse로 priority 적용 전후 LCP 비교
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.