Next.js Image Optimizasyonu: next/image Rehberi

Next.js Image Optimizasyonu: next/image Rehberi
Görseller, web sayfalarının en ağır bileşenleridir ve optimize edilmediğinde sayfa performansını ciddi şekilde etkiler. Next.js'in next/image bileşeni, otomatik boyutlandırma, lazy loading, format dönüşümü ve responsive tasarım gibi optimizasyonları yerleşik olarak sunar. Bu rehberde next/image'ın tüm özelliklerini ve en iyi kullanım pratiklerini inceleyeceğiz.
Temel Kullanım
next/image bileşeni, standart HTML <img> etiketinin gelişmiş bir versiyonudur:
import Image from 'next/image';
export default function Hero() {
return (
<div className="relative h-[500px]">
<Image
src="/images/hero-banner.jpg"
alt="Ana sayfa banner görseli"
fill
priority
className="object-cover"
/>
</div>
);
}
Lokal ve Remote Görseller
import Image from 'next/image';
import profilePic from '@/public/images/profile.jpg'; // Statik import
export default function Profile() {
return (
<div>
{/* Statik import — boyutlar otomatik belirlenir */}
<Image
src={profilePic}
alt="Profil fotoğrafı"
placeholder="blur" // Statik import'ta otomatik blur
/>
{/* Remote görsel — boyut belirtmek zorunlu */}
<Image
src="https://example.com/photo.jpg"
alt="Remote görsel"
width={800}
height={600}
/>
</div>
);
}
Remote Pattern Konfigürasyonu
Remote görselleri kullanmak için next.config.js'te izin verilen domain'leri tanımlayın:
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.unsplash.com',
},
{
protocol: 'https',
hostname: '*.amazonaws.com',
},
{
protocol: 'https',
hostname: 'cdn.example.com',
pathname: '/images/**',
},
],
},
};
module.exports = nextConfig;
*) kullanımına dikkat edin. Güvenlik için mümkün olduğunca spesifik pattern'ler tanımlayın.
Fill Mode ve Responsive Görseller
import Image from 'next/image';
// Fill mode — parent container'ı doldurur
export function HeroImage() {
return (
<div className="relative w-full h-[400px]">
<Image
src="/images/hero.jpg"
alt="Hero"
fill
sizes="100vw"
className="object-cover rounded-lg"
priority
/>
</div>
);
}
// Responsive grid görselleri
export function ImageGrid({ images }: { images: ImageType[] }) {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{images.map((img) => (
<div key={img.id} className="relative aspect-video">
<Image
src={img.url}
alt={img.alt}
fill
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
className="object-cover rounded-lg"
/>
</div>
))}
</div>
);
}
sizes prop'u, tarayıcıya hangi genişlikte hangi boyutta görsel kullanacağını söyler. Doğru sizes değeri, gereksiz büyük görsellerin indirilmesini önler.
Priority ve Lazy Loading
import Image from 'next/image';
export default function Page() {
return (
<>
{/* LCP görseli — priority ile preload edilir */}
<Image
src="/images/above-fold.jpg"
alt="Ana görsel"
width={1200}
height={600}
priority // Lazy loading devre dışı, preload eklenir
/>
{/* Sayfa aşağısındaki görseller — varsayılan lazy loading */}
<Image
src="/images/below-fold.jpg"
alt="Alt görsel"
width={800}
height={400}
loading="lazy" // Varsayılan
/>
</>
);
}
Placeholder ve Blur Effect
import Image from 'next/image';
// Statik import ile otomatik blur
import heroImage from '@/public/hero.jpg';
export function BlurExample() {
return (
<Image
src={heroImage}
alt="Blur placeholder örneği"
placeholder="blur" // Otomatik blur data URL oluşturulur
/>
);
}
// Remote görsel için manuel blurDataURL
export function RemoteBlurExample() {
return (
<Image
src="https://example.com/photo.jpg"
alt="Remote blur"
width={800}
height={600}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRg..."
/>
);
}
// Renk placeholder
export function ColorPlaceholder() {
return (
<div className="relative aspect-video bg-gray-200">
<Image
src="/images/photo.jpg"
alt="Renk placeholder"
fill
placeholder="empty" // Varsayılan — placeholder yok
/>
</div>
);
}
Image Konfigürasyonu
// next.config.js
const nextConfig = {
images: {
// Desteklenen formatlar
formats: ['image/avif', 'image/webp'],
// Üretilecek boyutlar
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
// Cache süresi (saniye)
minimumCacheTTL: 60 * 60 * 24 * 30, // 30 gün
// Harici loader (Cloudinary, Imgix vb.)
// loader: 'custom',
// loaderFile: './lib/image-loader.ts',
// Optimizasyonu devre dışı bırak (önerilmez)
// unoptimized: true,
},
};
Custom Image Loader
// lib/image-loader.ts
export default function cloudinaryLoader({
src,
width,
quality,
}: {
src: string;
width: number;
quality?: number;
}) {
const params = [
`f_auto`,
`c_limit`,
`w_${width}`,
`q_${quality || 'auto'}`,
];
return `https://res.cloudinary.com/demo/image/upload/${params.join(',')}${src}`;
}
// Kullanım
import Image from 'next/image';
<Image
loader={cloudinaryLoader}
src="/my-image.jpg"
alt="Cloudinary görsel"
width={800}
height={600}
/>
Performans İpuçları
- Above-the-fold görsellere
priorityekleyin - Her zaman
alttext kullanın (erişilebilirlik ve SEO) sizesprop'unu doğru ayarlayın- Statik görseller için import kullanarak otomatik blur placeholder alın
- Dekoratif görsellerde
alt=""kullanın - Büyük görselleri
fillmode ile responsive yapın
Sonuç
Next.js next/image bileşeni, görsel optimizasyonunu otomatikleştirerek Core Web Vitals skorlarını önemli ölçüde iyileştirir. Lazy loading, format dönüşümü, responsive boyutlandırma ve cache mekanizması gibi özelliklerle minimum çabayla maksimum performans elde edersiniz. Priority ve sizes prop'larını doğru kullanmak, LCP metriğinizi doğrudan etkiler.