Next.js 16.3 ve Instant Navigations: Sunucu Gücüyle SPA Hızı

Paylaş:
Next.js 16.3 ve Instant Navigations: Sunucu Gücüyle SPA Hızı - blog yazısı görseli

Modern web geliştirme dünyasında, sunucu taraflı render (SSR - Server Side Rendering) ve istemci taraflı tek sayfa uygulamaları (SPA - Single Page Applications) arasındaki çekişme yıllardır devam ediyor. Sunucu taraflı mimariler mükemmel ilk yükleme performansı, SEO avantajları ve güvenli veri yönetimi sunarken; istemci taraflı SPA'ler ise kullanıcı bir bağlantıya tıkladığında anında tepki veren, sayfa geçişlerinin pürüzsüz ve kesintisiz olduğu o meşhur "snappy" (akıcı) kullanıcı deneyimini vaat ediyor.

Next.js ekibi, React Server Components (RSC) mimarisiyle bu iki dünya arasındaki köprüyü kurmaya çalışsa da, sunucu bileşenlerinin doğası gereği navigasyonların yavaş hissettirdiği yönündeki eleştiriler uzun süredir gündemdeki yerini koruyordu. Bir sunucu bileşenine yönlenirken ağ gecikmesi yaşanması, kullanıcının tıklama yaptıktan sonra yeni sayfanın yüklenmesini beklemesine ve bu esnada ekranda hiçbir değişiklik görmemesine neden oluyordu. Bu da uygulamalara modern bir mobil uygulama veya SPA havasından ziyade, eski tarz "klasik web sitesi" hissi veriyordu.

İşte Next.js 16.3 Preview (Önizleme) sürümü, bu köklü sorunu kökünden çözmeyi hedefleyen devasa bir özellik setiyle geliyor: Instant Navigations (Anlık Gezintiler). Bu yeni özellik grubu, Next.js uygulamalarının sunucu tabanlı modelin sunduğu tüm avantajları korurken, istemci taraflı SPA'lerin hızına ve yanıt verebilirliğine kavuşmasını sağlıyor.

Klasik Navigasyon Neden Yavaş Hissettirir?

Geleneksel bir sunucu tabanlı uygulamada kullanıcı bir bağlantıya tıkladığında süreç şu şekilde işler:

1. Kullanıcı linke tıklar. 2. Tarayıcı veya Next.js router, sunucuya yeni rotanın verilerini ve bileşen ağacını istemek üzere bir ağ isteği gönderir. 3. Sunucu veritabanına sorgu atar, API'lerden verileri çeker ve bileşenleri render eder. 4. Ağ üzerinden yanıt istemciye geri döner. 5. Next.js router yeni sayfayı ekrana çizer.

Bu süreçte 2. ve 4. adımlar arasındaki süre boyunca istemcide hiçbir görsel değişiklik olmaz. Eğer kullanıcının internet bağlantısı yavaşsa veya sunucu veriyi çekerken 1-2 saniyelik bir gecikme yaşıyorsa, kullanıcı sanki uygulama donmuş gibi hisseder.

Buna karşın, istemci odaklı bir SPA'de (örneğin React Router kullanan klasik bir React projesi) süreç farklıdır. Kod zaten istemcide olduğu için, kullanıcı linke tıkladığı an sayfa kabuğu (shell) ve yükleniyor animasyonları (skeleton loader) anında ekrana gelir. Veriler arka planda yüklenmeye devam ederken, kullanıcı uygulamanın çalıştığını ve tepki verdiğini görür.

Next.js 16.3, geliştiricilere sunduğu yeni optimizasyonlar ve mimari değişikliklerle bu iki yaklaşımı birleştiriyor. Artık sunucu tarafındaki asenkron işlemlerin tamamlanmasını beklemeden, sayfa geçişleri anlık olarak başlatılabiliyor.

İlk Adım: Cache Components Özelliğini Etkinleştirmek

Instant Navigations dünyasına adım atmak için ilk yapılması gereken şey, Next.js konfigürasyon dosyasında yeni cacheComponents bayrağını aktif hale getirmektir:

typescript
// next.config.ts
import type { NextConfig } from 'next';
 
const nextConfig: NextConfig = {
  cacheComponents: true,
  // Diğer ayarlarınız...
};
 
export default nextConfig;

Next.js ekibi son bir yıldır framework'ü köklerine döndürmek için çalışyor: Varsayılan olarak dinamik, arkada gizli veya kafa karıştırıcı önbellek mekanizmaları barındırmayan net bir yapı. cacheComponents bayrağı, bu yeni basitleştirilmiş ve tahmin edilebilir önbellek davranışlarını projenize dahil ediyor. Vercel ekibi, bu bayrağın gelecekteki bir sonraki majör Next.js sürümünde varsayılan olarak etkin geleceğini belirtiyor.

Seçim Sizin: Stream (Akış), Cache (Önbellek) veya Block (Engelleme)

cacheComponents etkinleştirildiğinde, bir rota sunucuda asenkron bir veri çekme işlemini (await) bekliyorsa, geliştirici olarak karşınıza üç farklı strateji çıkıyor. Bu stratejiler sayesinde sayfanın anlık olarak mı açılacağını yoksa sunucu yanıtını bekleyeceğini kontrol edebiliyorsunuz:

1. Stream (React ile Akış)

Eğer veri çekme işleminizi bir sınırı içine alırsanız, Next.js kullanıcı bağlantıya tıkladığı an sayfa geçişini başlatır. Kullanıcı anında fallback olarak tanımladığınız yüklenme arayüzünü (skeleton, spinner vb.) görür. Sunucuda veri çekme işlemi tamamlandıkça, gerçek arayüz bileşenleri istemciye akar (stream) ve yüklenme alanlarının yerini alır. Bu sayede sayfa geçişi tamamen anlık ve SPA-benzeri hissettirir.

2. Cache ('use cache' ile Önbellekleme)

Eğer arayüzün veya verinin bir kısmı önbelleğe alınabiliyorsa, Next.js 15 ile hayatımıza giren ve Next.js 16 ile olgunlaşan 'use cache' direktifini kullanabilirsiniz. Kullanıcı linke tıkladığı anda, daha önce önbelleğe alınmış olan hazır arayüz anında ekrana gelir. Arka planda ise güncel veri gerekiyorsa revalidate süreçleri tetiklenebilir. Kullanıcı için bekleme süresi sıfıra iner.

3. Block (Engelleme - export const instant = false)

Bazı durumlarda, bir sayfa geçişinde asla yüklenme ekranı veya eski önbellek verisi göstermek istemeyebilirsiniz. Örneğin, bir haber portalında veya blog yazısında, makale başlığı ve içeriği tamamen hazır olmadan kullanıcının sayfaya geçmesini istemiyorsunuzdur. Bu gibi durumlar için ilgili sayfa (page.tsx) veya yerleşim (layout.tsx) dosyasında navigasyonun \"anlık\" olmasını devre dışı bırakabilirsiniz:

typescript
// app/blog/[slug]/page.tsx
export const instant = false;

export default async function BlogPost({ params }: { params: { slug: string } }) {
  const post = await fetchBlogPost(params.slug);
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

export const instant = false; satırını eklediğinizde, Next.js bu sayfaya yapılan navigasyonları sunucuya bağımlı hale getirir. Rota geçişi, sunucu tarafındaki tüm veri çekme işlemleri bitene kadar \"bloklanır\". Böylece kullanıcı ancak sayfa tamamen render edildikten sonra geçişi görür. Bu sayede uygulamanızdaki hangi sayfaların anlık açılacağını, hangilerinin ise geleneksel yöntemle bekleteceğini tamamen siz belirlersiniz.

Geliştirme Sürecinde Hızlı Navigasyonu Korumak: Instant Insights ve Playwright

Geliştirme yaparken yanlışlıkla anlık olması gereken bir sayfada engelleyici (blocking) bir işlem yapmak oldukça kolaydır. Bir bileşenin içine asenkron bir await eklemek, tüm sayfa geçişinin anlık yapısını bozabilir.

Next.js 16.3, bu tür performans gerilemelerini (regressions) önlemek için Instant Insights adında yeni bir paneli geliştirme sunucusuna entegre ediyor. Eğer anlık olması beklenen bir rotada navigasyon yavaşlarsa veya bloklanırsa, Next.js DevTools arayüzünde otomatik olarak bir uyarı/hata paneli beliriyor ve sizi yavaş navigasyona neden olan kod satırına yönlendiriyor.

Bunun yanı sıra, test süreçlerinde de bu durumu garanti altına alabilmeniz için Playwright test yardımcısı geliştirildi. @next/playwright paketinden içe aktarılan instant fonksiyonu, testler sırasında sayfa geçişinin ağ gecikmesi olmadan anında gerçekleşip gerçekleşmediğini doğrulamaya yarıyor:

typescript
import { expect, test } from '@playwright/test';
import { instant } from '@next/playwright';
 
test('urun basligi aninda gorunur olmalidir', async ({ page }) => {
  await page.goto('/products/shoes');
 
  // Ag isteginin tamamlanmasini beklemeden anlik durumu test et
  await instant(page, async () => {
    await page.click('a[href="/products/hats"]');
    await expect(page.locator('h1')).toContainText('Beyzbol Şapkası');
    await expect(page.getByText('Stok kontrol ediliyor...')).toBeVisible();
  });
 
  // Ag istegi tamamlandiktan sonra nihai durumu test et
  await expect(page.getByText('12 adet stokta')).toBeVisible();
});

Yukarıdaki test örneğinde, instant bloğu içerisindeki kodlar, linke tıklandığı an ağ yanıtı henüz sunucudan dönmeden önce istemci tarafında neyin görünür olduğunu doğrular. Eğer linke tıklandığında anında \"Beyzbol Şapkası\" başlığı ve \"Stok kontrol ediliyor...\" fallback metni ekranda belirmezse test başarısız olur. Bu sayede uygulamanızın SPA hissi veren yapısının bozulmadığından emin olabilirsiniz.

Prefetching Mekanizmasında Devrim: Kısmi Ön Belleğe Alma (Partial Prefetching - PPR)

Navigasyonların anlık hissettirmesi için çözülmesi gereken iki temel engel vardır:

1. İstemci ile sunucu arasındaki ağ mesafesi (gecikme süresi - latency). 2. Sunucunun yanıtı hazırlama süresi.

Streaming ve Caching ile ikinci engeli (sunucu tarafındaki bekleme süresini) aşabiliyoruz. Peki ya ağ gecikmesini nasıl minimize edeceğiz?

Next.js önceki sürümlerde bu problemi çözmek için agresif bir prefetch (ön yükleme) politikası izliyordu. Ekrandaki her bir bileşeni için arka planda sunucuya ayrı bir prefetch isteği gönderiliyordu. Eğer bir sayfada (örneğin bir mesajlaşma uygulamasının kenar çubuğunda) 20 farklı sohbet bağlantısı varsa, Next.js bu 20 bağlantının her biri için ayrı ayrı prefetch istekleri ateşliyordu. Bu durum, özellikle mobil cihazlarda ve yüksek trafikli sitelerde ciddi bir ağ yükü ve sunucu maliyeti yaratıyordu. Geliştiriciler Network sekmesinde düzinelerce aynı rotaya işaret eden istekler görmekten haklı olarak şikayetçiydi.

Next.js 16.3, bu sorunu çözmek için modern SPA'lerin kullandığı bir yöntemi ödünç alıyor: Kısmi Ön Belleğe Alma (Partial Prefetching - PPR).

Artık Next.js, her bir link için ayrı ayrı prefetch isteği yapmak yerine, her benzersiz rota için tek bir ortak \"yükleme kabuğu\" (loading shell) hazırlar ve prefetch eder. Örneğin, /chat/1, /chat/2, /chat/3 gibi 20 farklı linkiniz varsa, Next.js sadece bir kere /chat/[id] rotasının statik yükleme şablonunu (shell) indirir ve bunu istemci belleğinde saklar. Kullanıcı bu 20 linkten hangisine tıklarsa tıklasın, istemci bu ortak shell'i anında ekrana basar. Rota bazlı bu yeni yaklaşım, hem ağ trafiğini dramatik ölçüde azaltıyor hem de uygulamaya mükemmel bir hız kazandırıyor.

Kısmi Ön Belleğe Alma özelliğini denemek için Next.js konfigürasyonunuza şu ayarı eklemeniz yeterlidir:

typescript
// next.config.ts
import type { NextConfig } from 'next';
 
const nextConfig: NextConfig = {
  cacheComponents: true,
  partialPrefetching: true, // PPR aktif
};
 
export default nextConfig;

Ayrıca bu ortak kabuk (shell) tabanlı prefetching, gelecekteki çevrimdışı (offline) çalışma desteği için de harika bir zemin hazırlıyor. İnternet bağlantısı anlık olarak kopsa dahi, istemci elindeki hazır shell'ler sayesinde sayfalar arası geçişi görsel olarak yapabilecek.

Hangi bileşenlerin statik kabuğun (shell) bir parçası olduğunu, hangilerinin ise dinamik olarak sunucudan yüklendiğini anlamak geliştirme aşamasında zor olabilir. Next.js 16.3 DevTools bünyesine eklenen Navigation Inspector (Gezinti Denetleyicisi) bu süreci tamamen görünür kılıyor.

Geliştirme sunucusunda bu aracı açtığınızda, bir linke tıkladığınızda navigasyonu duraklatabiliyorsunuz. Bu sayede Next.js size sadece prefetch edilmiş statik shell'i (yani kullanıcının tıklama anında saniyenin onda birinde göreceği ilk ekranı) gösterir. \"Resume\" (Devam Et) butonuna bastığınızda ise ağ isteği tamamlanır ve dinamik veriler ekrana gelir. Bu görsel denetleyici, uygulamanızın ilk saniyede kullanıcıya nasıl yansıyacağını analiz etmenizi son derece kolaylaştırır.

Varsayılan olarak Partial Prefetching, ağ trafiğini düşük tutmak amacıyla sadece rotanın temel statik kabuğunu prefetch eder. Ancak bazı kritik durumlarda, sadece kabuğu değil, verinin veya dinamik bileşenlerin de prefetch edilmesini isteyebilirsiniz. Örneğin, e-ticaret sitenizdeki ana menüde yer alan \"Kampanyalar\" sayfasının başlığının ve öne çıkan görselinin kullanıcı tıklamadan önce hazır olmasını isteyebilirsiniz.

Bu tür durumlarda, ilgili bağlantıya özelliğini ekleyerek daha derinlemesine bir prefetch tetikleyebilirsiniz. Bu durumda Next.js, derleme (build) zamanında bilinen veya 'use cache' ile işaretlenmiş olan tüm bileşenleri de prefetch paketine dahil eder.

Eğer çalışma zamanında (runtime) önbelleğe alınmış verilerin de prefetch edilmesini istiyorsanız, sayfa bileşeninizde şu yapılandırmayı kullanabilirsiniz:

typescript
export const prefetch = 'allow-runtime';

Bu ayar sayesinde, dinamik olarak değişen ama önbellekte (cache) yer alan veriler de prefetch istekleriyle istemciye taşınır. Böylece sayfa geçişleri sadece kabuk seviyesinde değil, içerik seviyesinde de tamamen sıfır gecikmeli hale gelir.

Gerçek Dünya Performansı: v0 Örnek Olayı (Case Study)

Vercel ekibi, bu yeni Instant Navigations ve Partial Prefetching araçlarını kendi geliştirdikleri popüler yapay zeka tasarım aracı v0 üzerinde aktif olarak test etti. v0, yoğun istemci etkileşimlerine sahip karmaşık bir web uygulaması olmasına rağmen, sayfa geçişlerindeki yavaşlıklar kullanıcı deneyimini olumsuz etkiliyordu.

Geliştirici ekibi, Next.js 16.3 Preview sürümünü v0'a entegre edip Instant Insights paneli yardımıyla engelleyici (blocking) rotaları tespit etti. Yavaş veri çekme işlemlerini sınırları arkasına taşıyarak ve bazı alanlarda 'use cache' kullanarak navigasyon sürelerini neredeyse sıfıra indirmeyi başardılar. Yapılan optimizasyonlar sonucunda, v0 kullanıcılarının linke tıklamasıyla rota değişimi arasındaki gecikme süresi dramatik bir şekilde azaldı.

Özet Olarak

Next.js 16.3 Preview sürümü, sunucu odaklı modern web mimarisini SPA'lerin pürüzsüz navigasyon hızıyla birleştirerek web geliştirme standartlarını bir adım yukarı taşıyor:

* Anlık Gezinti Deneyimi: Stream ve Cache yöntemleriyle sayfa geçişlerindeki ağ bekleme süreleri tamamen eleniyor. * Esnek Denetim: Gerekli yerlerde export const instant = false; ile geleneksel engelleyici navigasyona geri dönülebiliyor. * Kısmi Ön Belleğe Alma (PPR): Her link için ayrı prefetch isteği yapmak yerine rota başına tek bir statik shell prefetch edilerek ağ yükü minimize ediliyor. * Gelişmiş Geliştirici Araçları: Navigation Inspector ve Playwright için instant() test yardımcısıyla performans kayıpları anında tespit ediliyor.

Next.js 16.3'ü projenizde denemek için terminalinizde şu komutu çalıştırabilirsiniz:

bash
npm install next@preview

Henüz önizleme aşamasında olduğu için üretim (production) ortamında kullanırken dikkatli olunması önerilse de, Next.js'in gelecekte web sitelerini ne kadar hızlı hale getireceğini görmek heyecan verici.

Makale Bilgileri

Yazar: İsmail Hakkı EREN
Benzer Konudaki Yazılar