Bỏ qua đến nội dung chính
image optimizationnext/imageperformanceLCPfrontend

Image Optimization Với next/image: Đầy Đủ Cho Production

Image optimization với next/image: srcset, sizes, priority, blur placeholder, CDN tự host vs Vercel/Cloudflare. Code production-ready, giảm LCP rõ rệt.

Xuất bản 7 phút đọc

Image optimization đúng giảm LCP 2-3x, save bandwidth 50-80%. Bài này deep-dive next/image — srcset, priority, sizes, placeholder — và setup CDN cho production scale.

Vì sao image quan trọng?

Image chiếm 50-70% bytes của page hiện đại. LCP element thường là hero image. Tối ưu image = quick win lớn nhất cho perf.

next/image cơ bản

import Image from 'next/image'

<Image
  src="/photo.jpg"
  alt="Mô tả ảnh có ý nghĩa"
  width={800}
  height={600}
/>

Next tự động:

  • Generate srcset cho nhiều viewport (640w, 750w, 828w, 1080w, 1200w...)
  • Convert sang WebP/AVIF nếu browser support
  • Lazy load (loading="lazy" mặc định)
  • Set width/height attribute → reserve space, tránh CLS

Responsive image với sizes

<Image
  src="/banner.jpg"
  alt="Banner"
  width={1200}
  height={630}
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 1200px"
/>

Đọc: mobile chiếm 100% viewport → browser pick srcset gần với viewport width. Tablet 50% → pick srcset = viewport/2. Desktop max 1200px.

Sai sizes thường gặp:

  • Bỏ sizes → browser pick lớn nhất → mobile tải 1200w trên 375w viewport
  • Sai breakpoint với CSS thực tế

priority cho LCP

// Hero — LCP element
<Image
  src="/hero.webp"
  alt="Hero"
  width={1920}
  height={1080}
  priority         // ← preload + bỏ lazy
  sizes="100vw"
/>

// Image dưới fold — không priority
<Image src="/section-2.jpg" alt="..." width={800} height={600} sizes="50vw" />

Mỗi page chỉ 1 priority image. Nhiều = race tải, đảo lộn LCP.

Blur placeholder

// Local image — blurDataURL auto generated
import hero from '@/public/hero.jpg'  // Next plugin tự process

<Image
  src={hero}
  alt="Hero"
  placeholder="blur"
  // blurDataURL auto inject
/>

// Remote image — phải tự cung cấp blurDataURL
const blurDataURL = 'data:image/jpeg;base64,/9j/4AAQ...' // generate qua plaiceholder lib

<Image
  src="https://cdn.alodev.vn/photo.jpg"
  alt="..."
  width={800}
  height={600}
  placeholder="blur"
  blurDataURL={blurDataURL}
/>

Fill mode cho responsive container

// Khi không biết kích thước cụ thể, dùng fill + parent có position: relative
<div style={{ position: 'relative', aspectRatio: '16/9' }}>
  <Image
    src="/banner.jpg"
    alt="Banner"
    fill
    sizes="100vw"
    style={{ objectFit: 'cover' }}
  />
</div>

CDN production: Cloudflare Images

Self-host Next.js resize tốn CPU + memory. Production scale dùng external image service:

// next.config.ts
export default {
  images: {
    loader: 'custom',
    loaderFile: './lib/image-loader.ts',
  },
}
// lib/image-loader.ts — Cloudflare Images
export default function loader({ src, width, quality }) {
  const params = ['format=auto', `width=${width}`, `quality=${quality || 75}`]
  return `https://imagedelivery.net/${ACCOUNT_HASH}/${src}/${params.join(',')}`
}

Cloudflare $5/100k delivery, edge cache 200+ POP. R2 + Workers Image Resizing là alternative rẻ hơn.

WebP, AVIF — chọn nào?

FormatKích thướcBrowser support
JPEG100% baselineMọi browser
WebP~70% JPEG97%+ browser
AVIF~50% JPEG92%+ browser (2026)

Next.js mặc định serve AVIF nếu Accept header hỗ trợ, fallback WebP, fallback JPEG. Anh không phải lo.

Checklist image optimization

  • ✅ Mọi <img> dùng next/image
  • ✅ width + height (hoặc fill + container có aspect-ratio)
  • ✅ alt mô tả ý nghĩa, không "image" generic
  • ✅ priority cho LCP image, lazy default cho rest
  • ✅ sizes prop khớp CSS breakpoint thực tế
  • ✅ Local image dùng import → auto blur
  • ✅ Remote image whitelist trong next.config.ts
  • ✅ Production: external CDN (Cloudflare Images, Imgix)
  • ✅ Format AVIF/WebP auto serve

Kết luận

Image optimization đúng là một trong những đầu tư có ROI cao nhất cho perf. next/image cover 90% case sẵn — chỉ cần dùng đúng API. Production scale: external CDN tránh backend Next resize tốn CPU. Tham khảo Web Vitals để đo impact thực tế lên LCP.

Zalo