개발 기록/Web

NextJS Image Optimization

시유후 2025. 10. 16. 12:33

What I do

AS - IS

  • style background-image attribute로 이미지 로드

TO - BE

  • next/image Image Component 사용 하여 로드
  • width, height 지정
  • minimumCacheTTL → Image caching
  • optimize with AVIF, WEBP
  • set Priority to Next Image(Main Page Top content → priority: “high”)
// Image Load With next/image Image Component
<Image
  src={imageURL}
  width={400}
  height={208}
  className="w-full h-full rounded-md"
  priority="high" // if top content, set priority 'high' for LCP, FCP
 />
// it change to below
<img src="https://[domain]/_next/image?url=[imageURL]&w=400&h=208&q=75"/>
// even if you not use next/image, you can use that api(_next/image?url=[imageURL])
// for image optimization (like when use dangerouslysetinnerhtml)
// next.config.ts image optimization config
const nextConfig: NextConfig = {
  images: {
    formats: ["image/avif", "image/webp"], // optimization for image size
    deviceSizes: [640, 750, 828, 1080, 1200, 1920],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
    minimumCacheTTL: 86400, // cache optimized image
  }
};

Problem Solving

  1. Accept Header가 전달되지 않는 이슈
    1. AWS CloudFront를 거치면서 Accept Header를 그대로 전달하지 않는 이슈
    2. AWS CloudFront - Behavior - Legacy cache전략 사용중.
    3. Accept를 헤더에 전달하도록 추가하여, Accept : 'image/avif image/webp … '가 전달되도록 변경
  2. CloudFlare에 이미지가 캐시되지 않는 이슈
    1. Next Image Component를 사용하여 _next/image?url=[imageurl] 로 들어와 cloudflare가 dynamic으로 판단해 캐시하지 않는 이슈
    2. 해당 next api (_next/image)로 들어오는 주소는 모두 cache를 하도록 cloudFlare - caching - cache rules에 rule로서 등록하여 반영
      | (http.request.full_uri contains "/_next/image") 해당 부분 추가 후 캐시 설정
  3. Background Image, z-index, layout 문제
    1. background image를 사용하지 않아 layout이 깨지는 문제 발생
    2. wrapper를 relative로, image를 absolute로 설정하여 문제 해결
 
 
<section id="image-section" className="flex flex-col relative">
  <div className="absolute z-0 rounded-md h-full">
   <Image
      src={imageURL}
      width={400}
      height={208}
      className="w-full h-full rounded-md"
      priority="high" // if top content, set priority 'high' for LCP, FCP
     />
  </div>
  <div className="z-5">
    [Image Above Contents]
  </div>  
</section>

Effect

  • LCP, FCP의 상승 효과 (measured by light house)
    • LCP : 6.5s → 4.8s
    • FCP : 2.4 → 1.7s