TypeScript

[Next.js 실전] Image 컴포넌트로 웹 성능 최적화하기

코샵 2024. 11. 18. 10:48
반응형

소개

웹 성능에서 이미지 최적화는 매우 중요한 요소입니다. Next.js의 Image 컴포넌트는 자동 이미지 최적화, 지연 로딩, 올바른 크기 조정 등 다양한 최적화 기능을 제공합니다. 이번 글에서는 Image 컴포넌트의 모든 기능과 최적화 방법을 자세히 알아보겠습니다.

Next.js Image 컴포넌트 기본 사용법

Image 컴포넌트의 기본적인 사용 방법입니다.

import Image from 'next/image';

function MyComponent() {
  return (
    <Image
      src="/images/profile.jpg"
      alt="Profile picture"
      width={500}
      height={300}
      priority={false}
    />
  );
}

반응형 이미지 처리

다양한 화면 크기에 대응하는 반응형 이미지 설정 방법입니다.

// 가변 너비 이미지
function ResponsiveImage() {
  return (
    <div style={{ width: '100%' }}>
      <Image
        src="/images/hero.jpg"
        alt="Hero image"
        layout="responsive"
        width={1920}
        height={1080}
        sizes="(max-width: 768px) 100vw,
               (max-width: 1200px) 50vw,
               33vw"
      />
    </div>
  );
}

// fill 속성을 사용한 컨테이너 채우기
function FillContainer() {
  return (
    <div style={{ position: 'relative', height: '300px' }}>
      <Image
        src="/images/background.jpg"
        alt="Background"
        fill
        style={{ objectFit: 'cover' }}
      />
    </div>
  );
}

이미지 품질 최적화

이미지 품질과 로딩 성능의 균형을 맞추는 방법입니다.

// 품질 설정
<Image
  src="/images/photo.jpg"
  alt="High quality photo"
  width={800}
  height={600}
  quality={75} // 1-100 사이의 값
/>

// 이미지 포맷 최적화
<Image
  src="/images/icon.png"
  alt="Icon"
  width={100}
  height={100}
  formats={['webp', 'avif']} // 브라우저 지원에 따라 최적의 포맷 선택
/>

로딩 최적화

이미지 로딩 방식을 최적화하는 다양한 방법입니다.

// 우선순위가 높은 이미지
<Image
  src="/images/hero.jpg"
  alt="Hero section"
  width={1200}
  height={600}
  priority={true} // LCP(Largest Contentful Paint) 이미지에 사용
/>

// 블러 처리된 플레이스홀더
<Image
  src="/images/large-image.jpg"
  alt="Large image"
  width={1200}
  height={800}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRg..." // 작은 base64 이미지
/>

외부 이미지 최적화

외부 도메인의 이미지를 최적화하는 방법입니다.

// next.config.js 설정
module.exports = {
  images: {
    domains: ['example.com', 'images.unsplash.com'],
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.example.com',
        pathname: '/images/**',
      },
    ],
  },
}

// 외부 이미지 사용
<Image
  src="https://images.unsplash.com/photo-123"
  alt="Unsplash image"
  width={800}
  height={600}
  loader={({ src, width, quality }) => {
    return `https://example.com/image/${src}?w=${width}&q=${quality || 75}`
  }}
/>

이미지 최적화 전략

다양한 상황에 따른 최적화 전략입니다.

// 아트 디렉션 (기기별 다른 이미지)
function ResponsiveArtDirection() {
  return (
    <>
      {/* 모바일용 이미지 */}
      <Image
        src="/images/hero-mobile.jpg"
        alt="Hero"
        width={375}
        height={300}
        className="block md:hidden"
      />
      {/* 데스크톱용 이미지 */}
      <Image
        src="/images/hero-desktop.jpg"
        alt="Hero"
        width={1200}
        height={600}
        className="hidden md:block"
      />
    </>
  );
}

// 이미지 갤러리 최적화
function Gallery() {
  return (
    <div className="grid grid-cols-3 gap-4">
      {images.map((image, index) => (
        <Image
          key={image.id}
          src={image.src}
          alt={image.alt}
          width={300}
          height={200}
          loading={index < 4 ? "eager" : "lazy"}
        />
      ))}
    </div>
  );
}

성능 모니터링

이미지 최적화 효과를 측정하는 방법입니다.

// next.config.js에서 성능 측정 설정
module.exports = {
  images: {
    deviceSizes: [640, 750, 828, 1080, 1200, 1920],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}

// Core Web Vitals 모니터링
export function ImageWithTracking() {
  return (
    <Image
      src="/image.jpg"
      alt="Tracked image"
      width={800}
      height={600}
      onLoadingComplete={(result) => {
        console.log('Image loaded:', result.naturalWidth);
        // 성능 메트릭 측정
      }}
    />
  );
}

주의사항

  1. width와 height는 항상 지정해야 합니다
  2. fill 속성 사용 시 부모 요소에 relative 포지션이 필요합니다
  3. 외부 이미지는 domains나 remotePatterns 설정이 필요합니다
  4. priority 속성은 필요한 경우에만 사용합니다

결론

Next.js의 Image 컴포넌트는 강력한 이미지 최적화 도구입니다. 올바른 설정과 사용 방법을 통해 웹사이트의 성능을 크게 향상시킬 수 있습니다. 특히 반응형 이미지 처리, 자동 최적화, 지연 로딩 등의 기능을 활용하면 사용자 경험을 크게 개선할 수 있습니다.