Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve nasıl temiz bir çözüm bulduğumu anlatacağım. Next.js ile dinamik sayfalar (`[slug].js`) oluştururken, `getStaticPaths` fonksiyonunda bir ikileme düşmüştüm. Binlerce ürün sayfam vardı ve hepsini build zamanında pre-render etmek saatler sürüyor, hatta bazen build hatasına bile yol açıyordu. "Sadece en popüler 50 sayfayı önceden oluştursam, geri kalanları isteğe bağlı (on-demand) oluştursam nasıl olur?" diye düşündüm ve `fallback` özelliğinin derinliklerine daldım.
Karşılaştığım İkilem
Projemde, bir e-ticet sitesinin ürün detay sayfalarını yapıyordum. Veritabanında 10.000'den fazla ürün vardı. `getStaticPaths` içinde tüm ürünlerin `slug` bilgisini çekip paths olarak döndürmek, her build'de 10.000+ statik sayfa oluşturulması demekti. Bu, build süresini inanılmaz uzatıyordu ve çoğu ürün için bu zahmete değmezdi çünkü trafiğin %80'i ilk 100 üründeydi. "Acaba hepsini pre-render etmeden, kullanıcı henüz görüntülemek istediğinde o sayfayı oluşturabilir miyiz?" sorusu kafamı kurcaladı.
Fallback: 'blocking' ile Çözümüm
Araştırmalarım sonucu, `fallback` parametresinin sadece `true` veya `false` olmadığını, `'blocking'` adında harika bir seçeneği olduğunu gördüm. İşte benim tercih ettiğim yöntem:
Bu yapıyı kurduğumda ne oldu? Build işlemi sadece 50 popüler sayfa için çalıştı ve saniyeler içinde bitti. Kullanıcı, önceden oluşturulmamış bir ürün sayfasına (örneğin `/urunler/az-bilen-bir-urun`) ilk kez girdiğinde, Next.js arkada sayfayı sunucuda (server-side) oluşturuyor ve bir sonraki istekler için bu statik dosyayı cache'liyor. Kullanıcıya boş bir sayfa veya yükleniyor çemberi gösterilmiyor (`fallback: true`'dan farkı bu), sayfa hazır olana kadar bekletiliyor. Mükemmel bir kullanıcı deneyimi!
getStaticProps'u Buna Göre Ayarlamak
Tabii ki `getStaticProps` fonksiyonunuz da bu stratejiye uygun olmalı. Olmayan bir slug geldiğinde 404 döndürmeyi unutmayın.
Burada aynı zamanda revalidate ile Incremental Static Regeneration (ISR) da kullandım. Yani, oluşturulmuş bir statik sayfa, en fazla 1 saat eski kalabilior, sonrasında bir istekte yeniden oluşturuluyor. Hem performans hem de güncel veri harika bir denge!
Sonuç olarak, bu `fallback: 'blocking'` stratejisi ile hem build sürelerimi ciddi oranda düşürdüm, hem de kullanıcılarım için hızlı ve sorunsuz bir site deneyimi sağladım. Siz Next.js'te büyük veri kümeleri ile çalışırken benzer bir strateji izliyor musunuz? `fallback: true` ile loading state'i göstermeyi mi tercih edersiniz, yoksa `'blocking'` ile kullanıcıyı bekletmeyi mi? Farklı senaryolarınız varsa yorumlarda paylaşın, tartışalım!
Projemde, bir e-ticet sitesinin ürün detay sayfalarını yapıyordum. Veritabanında 10.000'den fazla ürün vardı. `getStaticPaths` içinde tüm ürünlerin `slug` bilgisini çekip paths olarak döndürmek, her build'de 10.000+ statik sayfa oluşturulması demekti. Bu, build süresini inanılmaz uzatıyordu ve çoğu ürün için bu zahmete değmezdi çünkü trafiğin %80'i ilk 100 üründeydi. "Acaba hepsini pre-render etmeden, kullanıcı henüz görüntülemek istediğinde o sayfayı oluşturabilir miyiz?" sorusu kafamı kurcaladı.
Araştırmalarım sonucu, `fallback` parametresinin sadece `true` veya `false` olmadığını, `'blocking'` adında harika bir seçeneği olduğunu gördüm. İşte benim tercih ettiğim yöntem:
JavaScript:
// pages/urunler/[slug].js
export async function getStaticPaths() {
// SADECE EN POPÜLER 50 ÜRÜNÜ PRE-RENDER ET
const popularProducts = await fetchPopularProducts(50); // Örnek fonksiyon
const paths = popularProducts.map((product) => ({
params: { slug: product.slug },
}));
return {
paths, // Sadece 50 tanesi build anında oluşturulacak
fallback: 'blocking', // Oluşturulmamış sayfalar için SSR benzeri davranış
};
}
Bu yapıyı kurduğumda ne oldu? Build işlemi sadece 50 popüler sayfa için çalıştı ve saniyeler içinde bitti. Kullanıcı, önceden oluşturulmamış bir ürün sayfasına (örneğin `/urunler/az-bilen-bir-urun`) ilk kez girdiğinde, Next.js arkada sayfayı sunucuda (server-side) oluşturuyor ve bir sonraki istekler için bu statik dosyayı cache'liyor. Kullanıcıya boş bir sayfa veya yükleniyor çemberi gösterilmiyor (`fallback: true`'dan farkı bu), sayfa hazır olana kadar bekletiliyor. Mükemmel bir kullanıcı deneyimi!
Tabii ki `getStaticProps` fonksiyonunuz da bu stratejiye uygun olmalı. Olmayan bir slug geldiğinde 404 döndürmeyi unutmayın.
JavaScript:
export async function getStaticProps({ params }) {
const { slug } = params;
const product = await fetchProductBySlug(slug); // Slug'a göre ürünü getir
if (!product) {
return {
notFound: true, // Ürün yoksa 404 sayfası göster
};
}
return {
props: {
product,
},
// Incremental Static Regeneration (ISR) ile 1 saat tazele
revalidate: 3600,
};
}
Burada aynı zamanda revalidate ile Incremental Static Regeneration (ISR) da kullandım. Yani, oluşturulmuş bir statik sayfa, en fazla 1 saat eski kalabilior, sonrasında bir istekte yeniden oluşturuluyor. Hem performans hem de güncel veri harika bir denge!
Sonuç olarak, bu `fallback: 'blocking'` stratejisi ile hem build sürelerimi ciddi oranda düşürdüm, hem de kullanıcılarım için hızlı ve sorunsuz bir site deneyimi sağladım. Siz Next.js'te büyük veri kümeleri ile çalışırken benzer bir strateji izliyor musunuz? `fallback: true` ile loading state'i göstermeyi mi tercih edersiniz, yoksa `'blocking'` ile kullanıcıyı bekletmeyi mi? Farklı senaryolarınız varsa yorumlarda paylaşın, tartışalım!