Optimasi Gambar di Next.js 16: Panduan next/image, AVIF, dan LCP
Panduan praktis optimasi gambar di Next.js 16 dengan next/image, AVIF, dan strategi LCP. Mencakup remotePatterns, custom loader CDN, self-hosting sharp, dan placeholder blur.
Optimasi gambar di Next.js 16 dilakukan lewat komponen next/image bawaan, yang secara otomatis mengubah gambar menjadi format modern (AVIF dan WebP), menerapkan lazy-loading, menghasilkan srcset responsif, serta mencegah Cumulative Layout Shift (CLS) berkat reservasi ruang yang akurat. Supaya skor Core Web Vitals sehat, satu gambar hero sebaiknya pakai prop priority, sementara gambar di bawah lipatan layar dimuat secara lazy. Panduan ini bahas konfigurasi, pola LCP, integrasi CDN pihak ketiga, dan jebakan umum yang sering muncul di produksi.
Next.js 16 menggunakan loader sharp bawaan dan mendukung output AVIF, WebP, serta JPEG/PNG otomatis melalui Image Optimization API di /_next/image.
Selalu set prop priority pada satu gambar LCP per halaman (biasanya gambar hero di atas lipatan layar) agar dimuat tanpa lazy-load.
Gunakan remotePatterns di next.config.ts untuk mengizinkan domain gambar eksternal. Properti domains sudah deprecated.
Saat self-hosting, pasang dependensi sharp dan pastikan cache .next/cache/images persisten antar deploy.
Untuk skala besar, alihkan optimasi ke CDN gambar (Cloudinary, Imgix, Bunny) dengan custom loader, supaya server Next.js tidak jadi bottleneck CPU.
Prop sizes wajib untuk gambar fill atau responsive agar browser memilih varian srcset yang tepat dan menghemat bandwidth sampai 60%.
Bagaimana next/image bekerja di Next.js 16
Komponen next/image bukan sekadar pengganti tag <img>. Setiap kali komponen ini dirender, Next.js menulis ulang URL sumber menjadi endpoint internal /_next/image?url=...&w=...&q=.... Endpoint ini, yang ditangani Image Optimization API, mengambil gambar asli, mengubah ukurannya ke lebar yang diminta browser, mengonversi ke format modern jika di-accept oleh klien (AVIF atau WebP), lalu menyimpannya di cache filesystem di .next/cache/images.
Pada Next.js 16, loader bawaan menggunakan library sharp, sebuah binding ke libvips yang sangat cepat. Di lingkungan Vercel, sharp sudah otomatis terpasang. Saat self-hosting Anda harus menambahkannya sebagai dependensi produksi. Hasil konversi disimpan dengan kunci cache (src, width, quality, format), sehingga permintaan kedua untuk dimensi yang sama dilayani langsung dari disk tanpa pemrosesan ulang CPU.
Selain konversi format, komponen ini juga: (1) menghasilkan atribut srcset dan sizes otomatis untuk responsive images, (2) menerapkan loading="lazy" dan decoding="async" secara default, (3) menyisipkan placeholder agar ruang gambar terreservasi sehingga CLS mendekati nol. Kalau Anda ingin mendalami pola App Router lainnya, lihat juga panduan data fetching dan caching di Next.js 16 yang membahas bagaimana cache gambar berinteraksi dengan Partial Prerendering.
Konfigurasi dasar dan remotePatterns
Pemakaian termudah adalah meletakkan gambar di folder /public dan mengimpornya secara statis. Next.js akan otomatis mendeteksi lebar dan tinggi asli, jadi Anda tidak perlu menuliskannya manual. Ini menghilangkan CLS sepenuhnya.
import Image from 'next/image';
import heroImg from '@/public/hero.jpg';
export default function Page() {
return (
<Image
src={heroImg}
alt="Tampilan dashboard aplikasi"
priority
placeholder="blur"
/>
);
}
Untuk gambar dari URL eksternal (misalnya dari CMS headless atau S3), Anda wajib mendaftarkan domain pada remotePatterns di next.config.ts. Tanpa pendaftaran ini Next.js akan menolak optimasi sebagai langkah keamanan, mencegah SSRF atau kontaminasi cache dari host yang tidak terpercaya.
Cara mengoptimasi LCP dengan priority dan fetchPriority
Largest Contentful Paint (LCP) adalah metrik Core Web Vitals yang mengukur waktu render elemen terbesar yang terlihat di viewport. Di sebagian besar halaman, kandidat LCP adalah gambar hero, banner produk, atau cover artikel. Agar memenuhi ambang batas "good" 2,5 detik dari Core Web Vitals, gambar ini tidak boleh di-lazy-load.
Tandai gambar tersebut dengan prop priority. Next.js akan menambahkan fetchpriority="high", menghapus loading="lazy", dan menyisipkan tag <link rel="preload" as="image"> di <head> dengan imagesrcset yang sesuai. Hasilnya, browser mulai mengunduh gambar bersamaan dengan HTML, jauh sebelum parser sampai ke tag <img>.
Untuk gambar di luar viewport awal, biarkan default saja. Lazy-loading akan menunda unduhan hingga gambar mendekati viewport, sehingga hemat bandwidth dan CPU. Pola ini bekerja sangat baik dengan Suspense streaming yang dibahas di panduan route handlers dan streaming.
Format AVIF, WebP, dan strategi fallback
AVIF (AV1 Image File Format) menawarkan kompresi 20–50% lebih baik daripada WebP pada kualitas visual setara, tapi waktu enkode-nya jauh lebih lama, sekitar 10–20 kali WebP. Trade-off ini penting saat self-hosting: server Anda akan menghabiskan lebih banyak CPU untuk konversi pertama, meski hasilnya di-cache untuk permintaan berikutnya.
Default Next.js 16 mendukung AVIF dan WebP secara bersamaan. Browser modern mengirim header Accept: image/avif sehingga Image API memilih format terbaik per klien. Kalau beban CPU jadi masalah, Anda bisa menonaktifkan AVIF:
// next.config.ts - hanya WebP, lebih cepat di-enkode
images: {
formats: ['image/webp'],
},
Untuk kasus khusus seperti foto produk dengan banyak detail halus, AVIF memberi ukuran file paling kecil. Untuk grafis UI dengan area datar besar, WebP saja sudah cukup. PNG dengan transparansi selalu dikonversi ke WebP (atau AVIF) tanpa kehilangan alpha channel.
Menggunakan CDN eksternal seperti Cloudinary atau Imgix
Saat trafik bertumbuh, melakukan optimasi gambar di server Next.js Anda sendiri jadi mahal, terutama di Vercel Hobby/Pro yang menagih per transformasi. Di project terakhir saya, kuota Image Optimization Vercel habis hanya dalam dua hari setelah satu artikel viral, dan sejak itu saya selalu setup CDN gambar sejak hari pertama. Solusi umumnya adalah mengalihkan transformasi ke CDN gambar khusus seperti Cloudinary, Imgix, Bunny, atau ImageKit. CDN ini menjalankan transformasi di edge, punya cache global, dan biasanya jauh lebih murah per gambar.
Implementasinya dengan custom loader. Anda hanya perlu menyediakan fungsi yang mengubah { src, width, quality } jadi URL final di CDN.
// components/CloudImage.tsx
import Image from 'next/image';
import loader from '@/lib/cloudinary-loader';
export function CloudImage(props: React.ComponentProps<typeof Image>) {
return <Image {...props} loader={loader} />;
}
Dengan loader ini, Next.js tidak akan memanggil Image Optimization API internal. Semua transformasi dilakukan Cloudinary. Anda tetap mendapat srcset, lazy-loading, dan placeholder dari komponen next/image.
Aspek
Built-in (sharp)
CDN Eksternal
Biaya transformasi
CPU server / kuota Vercel
Tagihan CDN per request
Latensi konversi pertama
200–800 ms (cold)
50–150 ms (edge)
Cache global
Hanya region deploy
Edge POPs di banyak benua
Setup awal
Nol konfigurasi
Akun + custom loader
Cocok untuk
< 1 juta gambar/bulan
Skala besar, audiens global
Format AVIF/WebP
Otomatis
Otomatis via f_auto
Self-hosting: sharp, cache, dan storage
Kalau Anda menjalankan Next.js 16 di luar Vercel (Docker, Kubernetes, atau VPS), ada tiga hal yang harus disiapkan agar optimasi gambar berjalan optimal di produksi.
1. Pasang sharp sebagai dependensi produksi
npm install sharp
# atau dengan output standalone
npm install --omit=dev sharp
Tanpa sharp, Next.js 16 akan menolak menjalankan Image Optimization API dan melempar error "sharp Module not found" saat permintaan pertama ke /_next/image. Saya pernah mengalami ini di build Docker minimal dan ngabisin satu sore mencari penyebabnya, jadi pastikan sharp ada di dependencies, bukan devDependencies.
2. Persistkan direktori cache
Direktori .next/cache/images berisi hasil konversi. Saat menggunakan Docker, mount volume agar cache bertahan antar restart container. Tanpa ini, setiap deploy memaksa konversi ulang seluruh gambar:
Batasi deviceSizes dan imageSizes agar penyerang tidak bisa membanjiri cache dengan ribuan kombinasi lebar. Default Next.js sudah aman, tapi untuk situs B2B yang hanya melayani layar desktop, Anda bisa memangkasnya:
Placeholder mengurangi perceived loading time dan mencegah flash visual. Next.js menyediakan tiga opsi: empty (default, ruang kosong), blur (blur 10x10 piksel yang dienkode base64), dan data:image/... kustom.
Untuk impor statis dari /public, cukup tulis placeholder="blur". Next.js otomatis menghasilkan blur data URL saat build:
import produkImg from '@/public/produk.jpg';
<Image src={produkImg} alt="Foto produk" placeholder="blur" />
Untuk gambar dari URL eksternal, Anda harus menyediakan blurDataURL sendiri. Trik populer adalah meminta CMS menyimpan placeholder 10px dan mengembalikannya bersama metadata gambar:
Library seperti plaiceholder bisa menghasilkan blur data URL di build time. Untuk performa perceived yang lebih baik, gunakan strategi dominant color, yaitu latar belakang single-color yang cocok dengan rata-rata warna gambar. Ini lebih ringan daripada blur tapi tetap menghilangkan flash putih.
Mengapa next/image saya lambat atau gagal?
Tiga penyebab paling umum:
Tidak ada cache antar deploy. Setiap kali Anda men-deploy ke server self-hosted tanpa volume persisten, semua konversi diulang dari nol. Solusi: mount volume atau pakai CDN eksternal.
Banyak gambar dengan dimensi unik. Kalau setiap gambar di-render dengan width dan quality berbeda-beda, cache tidak pernah hit. Konsolidasikan pemakaian ke set sizes dan quality yang konsisten.
Tidak ada sizes pada gambar fill. Tanpa sizes, browser mengasumsikan 100vw, memilih varian terlebar, dan menghabiskan bandwidth. Selalu deklarasikan sizes yang merefleksikan tata letak responsif sesungguhnya.
Untuk debugging lanjutan, aktifkan log unoptimized di development dan periksa header X-Nextjs-Cache pada response /_next/image. Nilai HIT menandakan dilayani dari disk, sedangkan MISS berarti konversi baru terjadi. Bila Anda mengelola halaman dengan banyak gambar dinamis sekaligus melindungi rute dengan proxy.ts, pastikan endpoint /_next/image/* dikecualikan dari logika autentikasi agar tidak memutus cache CDN.
Pertanyaan yang Sering Diajukan
Apakah next/image gratis digunakan di Vercel?
Komponen next/image sendiri gratis dan open-source. Tapi di Vercel, setiap transformasi unik (kombinasi src, width, quality) dihitung sebagai satu Image Optimization request. Paket Hobby memberi 5.000 transformasi/bulan, Pro memberi 10.000. Untuk lebih dari itu, alihkan ke CDN gambar eksternal dengan custom loader.
Apa perbedaan next/image dan tag <img> biasa?
Tag <img> hanya menampilkan file apa adanya, tanpa konversi format, tanpa srcset otomatis, tanpa reservasi ruang. next/image menambahkan optimasi format (AVIF/WebP), lazy-loading, srcset responsif, dan pencegahan CLS, semuanya tanpa konfigurasi tambahan.
Bagaimana cara menggunakan gambar SVG di next/image?
Untuk alasan keamanan, optimasi SVG dimatikan secara default karena SVG bisa berisi JavaScript. Anda perlu mengaktifkan dangerouslyAllowSVG: true dan contentDispositionType: 'attachment' di konfigurasi images, plus contentSecurityPolicy yang ketat. Untuk SVG dari sumber tepercaya seperti folder public Anda sendiri, gunakan tag <img> atau impor sebagai komponen React.
Mengapa LCP saya tetap buruk meski sudah pakai priority?
Prop priority hanya membantu kalau gambar memang elemen LCP. Periksa lewat Lighthouse atau PageSpeed Insights elemen mana yang benar-benar LCP. Sering kali itu blok teks besar atau hero overlay, bukan gambar. Selain itu, pastikan sizes akurat, server merespons cepat (TTFB < 600 ms), dan tidak ada CSS yang menyembunyikan gambar saat render pertama.
Apakah AVIF didukung semua browser di 2026?
Ya, dukungan AVIF kini melampaui 96% browser global menurut caniuse.com. Chrome, Edge, Firefox, Safari 16+, dan Samsung Internet semuanya mendukungnya. Browser lama yang tidak mendukung AVIF otomatis menerima WebP atau JPEG dari Next.js karena Image API membaca header Accept klien.
Panduan praktis Parallel Routes dan Intercepting Routes di Next.js 16: dari konvensi @slot, pola (.) (..) (...), modal URL-addressable, dashboard multi-panel, default.tsx, error handling, sampai implikasi SEO dan caching — dengan contoh kode siap pakai.
Panduan lengkap migrasi middleware.ts ke proxy.ts di Next.js 16 — mulai dari codemod otomatis, pola autentikasi dan CORS, rate limiting, A/B testing, pelajaran dari CVE-2025-29927, hingga best practice produksi.
Panduan lengkap Route Handlers di Next.js 16 — dari REST API CRUD, validasi Zod, CORS, streaming SSE, webhook Stripe, file upload, caching dengan use cache, hingga rate limiting. Semua dengan contoh kode siap produksi.