Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve nasıl çözdüğümü anlatacağım. Next.js'in Image component'i gerçekten harika, performans ve görsel optimizasyon konusunda inanılmaz. Ama bu component'i kullanırken, özellikle dinamik veya boyutunu bilmediğim görsellerde, sayfa yüklenirken elementlerin yer değiştirmesi (layout shift) beni deli ediyordu. İşte bu can sıkıcı sorunu nasıl çözdüğümü paylaşacağım.
Sorunun Kökeni: Görünmez Görseller
Sorun şu: Next.js Image component'i, görsel yüklenmeden önce, ona verdiğin width ve height değerlerine göre bir alan ayırıyor. Eğer bu değerleri vermezsen veya yanlış verirsen, görsel yüklenene kadar o alan 0x0 piksel olarak kalıyor. Görsel yüklendiği anda da sayfa aniden kayıyor, butonlar, yazılar yer değiştiriyor. Hem kullanıcı deneyimi kötü hem de Core Web Vitals'tan Cumulative Layout Shift (CLS) puanını yiyorsun.
Çözüm Yolum: fill, sizes ve objectFit Üçlüsü
Benim en çok işime yarayan ve artık standart olarak kullandığım yöntem, fill prop'u ile birlikte sizes ve objectFit prop'larını kullanmak. Bu yöntem, özellikle boyutunu önceden bilemediğim (CMS'ten gelen, kullanıcı yükleyen) görseller için biçilmiş kaftan.
İşte tipik bir kullanımım:
Burada olanları açıklayayım:
1. Ana div'e relative pozisyon ve kesin bir yükseklik (height) verdim. Bu, container'ın boyutunu sabitler ve layout shift'u engeller.
2. Image component'ine fill prop'unu ekledim. Bu, görselin container'ı tamamen dolduracağı anlamına gelir.
3. sizes prop'u, tarayıcıya görselin hangi ekran genişliğinde hangi boyutta yükleneceğini söyler. Bu, responsive görseller için çok önemli.
4. className="object-cover" ile görselin container'a nasıl sığacağını belirttim. object-contain veya object-fill de kullanabilirsiniz.
İkinci Yöntem: Statik Görseller için Sabit Boyut
Eğer projenizdeki görsellerin boyutlarını biliyorsanız (örneğin, logo, icon, sabit banner'lar), o zaman en basit ve en etkili çözüm, width ve height değerlerini doğrudan vermek.
Bu kadar! Next.js, bu değerleri kullanarak görsel için doğru oranda alanı (aspect ratio) ayıracak ve hiçbir kayma olmayacak.
Sonuç ve Tavsiyem
Bu iki yöntemi uyguladıktan sonra, sayfalarımdaki layout shift neredeyse sıfırlandı. Lighthouse skorlarımda CLS artık hep yeşil!
fill + container boyutu yöntemi, dinamik içeriklerde hayat kurtarıcı. Sabit width/height yöntemi ise kontrolün sizde olduğu statik asset'ler için en iyisi.
Peki siz Next.js'te Image component'ini kullanırken layout shift sorunu yaşadınız mı? Bu yöntemler dışında farklı bir trick'iniz var mı? Ben onLoadingComplete callback'i ile bazı özel animasyonlar yapmayı da denedim, belki onu da başka bir yazıda konuşuruz. Yorumlarda deneyimlerinizi paylaşın!
Sorun şu: Next.js Image component'i, görsel yüklenmeden önce, ona verdiğin width ve height değerlerine göre bir alan ayırıyor. Eğer bu değerleri vermezsen veya yanlış verirsen, görsel yüklenene kadar o alan 0x0 piksel olarak kalıyor. Görsel yüklendiği anda da sayfa aniden kayıyor, butonlar, yazılar yer değiştiriyor. Hem kullanıcı deneyimi kötü hem de Core Web Vitals'tan Cumulative Layout Shift (CLS) puanını yiyorsun.
Benim en çok işime yarayan ve artık standart olarak kullandığım yöntem, fill prop'u ile birlikte sizes ve objectFit prop'larını kullanmak. Bu yöntem, özellikle boyutunu önceden bilemediğim (CMS'ten gelen, kullanıcı yükleyen) görseller için biçilmiş kaftan.
İşte tipik bir kullanımım:
JavaScript:
import Image from 'next/image';
const MyDynamicImage = ({ imageUrl, altText }) => {
return (
<div className="relative w-full h-[400px] md:h-[500px]">
<Image
src={imageUrl}
alt={altText}
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
className="object-cover"
priority={true} // LCP olabilecek görseller için
/>
</div>
);
};
Burada olanları açıklayayım:
1. Ana div'e relative pozisyon ve kesin bir yükseklik (height) verdim. Bu, container'ın boyutunu sabitler ve layout shift'u engeller.
2. Image component'ine fill prop'unu ekledim. Bu, görselin container'ı tamamen dolduracağı anlamına gelir.
3. sizes prop'u, tarayıcıya görselin hangi ekran genişliğinde hangi boyutta yükleneceğini söyler. Bu, responsive görseller için çok önemli.
4. className="object-cover" ile görselin container'a nasıl sığacağını belirttim. object-contain veya object-fill de kullanabilirsiniz.
Eğer projenizdeki görsellerin boyutlarını biliyorsanız (örneğin, logo, icon, sabit banner'lar), o zaman en basit ve en etkili çözüm, width ve height değerlerini doğrudan vermek.
JavaScript:
import logo from '/public/logo.png';
<Image
src={logo}
alt="Site Logosu"
width={200} // Görselin gerçek genişliği
height={50} // Görselin gerçek yüksekliği
priority
/>
Bu kadar! Next.js, bu değerleri kullanarak görsel için doğru oranda alanı (aspect ratio) ayıracak ve hiçbir kayma olmayacak.
Bu iki yöntemi uyguladıktan sonra, sayfalarımdaki layout shift neredeyse sıfırlandı. Lighthouse skorlarımda CLS artık hep yeşil!
fill + container boyutu yöntemi, dinamik içeriklerde hayat kurtarıcı. Sabit width/height yöntemi ise kontrolün sizde olduğu statik asset'ler için en iyisi.
Peki siz Next.js'te Image component'ini kullanırken layout shift sorunu yaşadınız mı? Bu yöntemler dışında farklı bir trick'iniz var mı? Ben onLoadingComplete callback'i ile bazı özel animasyonlar yapmayı da denedim, belki onu da başka bir yazıda konuşuruz. Yorumlarda deneyimlerinizi paylaşın!