Next.js 16, Önbellek Bileşenleri ve React Derleyicisi: gerçekte ne değişiyor
· 6 min read · Filippo Spinella · Next.js, React, Frontend, Performance
Yıllardır Next.js'deki en sinir bozucu sorulardan biri şuydu: "Bu sayfa statik mi yoksa dinamik mi?". cookies()'a bir çağrı, farklı seçeneklere sahip bir fetch, bir veritabanı istemcisi, bir CMS, bir alışveriş sepeti veya bir parça özel içerik ekleyene kadar bu basit bir soru gibi görünüyor.
Next.js 16 ilginç çünkü bu konuşmayı daha az gizemli hale getirmeye çalışıyor. Karmaşıklığı ortadan kaldırmaz ancak zihinsel modeli değiştirir: rotalar varsayılan olarak dinamiktir, önbellek ihtiyaç duyulan yerde kendini bildirir ve Suspense taze kalan parçalarla hızlı kabuklar oluşturmanın doğal yolu haline gelir.
Anlaşılması gereken özellik Önbellek Bileşenleridir. Stable Turbopack, React Compiler, proxy.ts ve yeni geçersiz kılma API'leri önemlidir, ancak aynı sorun etrafında dönerler: çerçevenin perde arkasında neye karar verdiğini tahmin etmek zorunda kalmadan hızlı uygulamalar oluşturmak.
Çünkü bu şey önemli
Gerçek bir uygulamada yalnızca "statik sayfalar" ve "dinamik sayfalar" yoktur. Farklı ihtiyaçlara sahip farklı parçalarınız var.
Ürün sayfası günde birkaç kez değişebilir. Fiyat daha sık değişebilir. Kullanılabilirlik neredeyse canlı olmalıdır. Kullanıcı adı kişiseldir. İncelemeler yayınlanabilir. Kenar çubuğu sabit olabilir. Araba öyle değil.
Her şeyi tek bir birim olarak ele alırsanız, her zaman iki uç noktadan biriyle karşılaşırsınız:
- agresif önbelleğe alma ve eski verileri görme riski;
- her yerde dinamik görüntü oluşturma ve performans gereğinden kötü.
Önbellek Bileşenleri tam olarak bu yanlış seçimi önlemeye hizmet eder.
Uygulamadaki model
cacheComponents: true ile, "use cache" kullanarak neyin önbelleğe alınabileceğini bildirebilirsiniz. Daha sonra süreyi ve etiketleri cacheLife() ve cacheTag() ile ilişkilendirebilirsiniz. Dinamik parçalar dinamik kalır ve Suspense ile izole edilebilir.
Kurulum küçük:
// next.config.ts import type { NextConfig } from 'next'; const nextConfig: NextConfig = { cacheComponents: true, }; export default nextConfig;
Büyük değişiklik yapılandırmada değil. Bileşenleri yazmaya nasıl başladığınızdır.
// app/products/[slug]/page.tsx import { Suspense } from 'react'; import { cacheLife, cacheTag } from 'next/cache'; async function getProduct(slug: string) { 'use cache'; cacheLife('hours'); cacheTag(`product:${slug}`); return db.product.findUnique({ where: { slug } }); } async function ProductDetails({ slug }: { slug: string }) { const product = await getProduct(slug); return ( <section> <h1>{product.name}</h1> <p>{product.description}</p> </section> ); } async function LiveInventory({ slug }: { slug: string }) { const inventory = await db.inventory.findFirst({ where: { slug } }); return <p>{inventory.quantity} pezzi disponibili</p>; } export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) { const { slug } = await params; return ( <> <ProductDetails slug={slug} /> <Suspense fallback={<p>Controllo disponibilità...</p>}> <LiveInventory slug={slug} /> </Suspense> </> ); }
Sayfanın tamamen önbelleğe alınmış veya tamamen dinamik olması gerekmez. Ürün sayfası hızlı ve tekrar kullanılabilir olabilir. Envanter taze kalabilir. Kullanıcı, en yavaş kısmı beklemeden bir şeyi hemen görür.
use cache yürütülebilir belgedir
"use cache"'ın hoşuma giden yanı, sizi niyetinizi açıkça ortaya koymaya zorlaması. Bir fonksiyonu okuduğunuzda birisinin "bu veriler yeniden kullanılabilir" diye karar verdiğini hemen anlarsınız.
fetch kullanmadığınız zamanlarda özellikle kullanışlıdır. Birçok uygulama Prisma, Drizzle, dahili SDK'lar, CMS istemcileri veya hizmet işlevlerinden verileri okur. Bu durumlarda, yalnızca fetch seçeneklerine dayanan eski mantık yeterli değildi.
Temel bir kural:
- önbellek içeriği nispeten stabildir;
- ayrıntılı etiketler kullanın;
- dinamik izinleri, oturumları, alışveriş sepetlerini, bildirimleri ve işlem durumlarını bırakır;
- yavaş parçaları
Suspenseiçine yerleştirin; - "Performansı artırdık" demeden önce ölçün.
Her şeyi atmadan geçersiz kılın
Önbellek yalnızca onu doğru bir şekilde güncelleyebiliyorsanız kullanışlıdır. Burada cacheTag, revalidateTag ve updateTag önem kazanıyor.
Örnek:
'use server'; import { updateTag } from 'next/cache'; export async function updateProductName(productId: string, name: string) { await db.product.update({ where: { id: productId }, data: { name }, }); updateTag(`product:${productId}`); }
Önemli detay etikettir. product:${productId} kesin bir sınır belirtir. products büyük bir kovayı anlatıyor. İlk başta devasa kova rahattır; Birkaç ay sonra, bir başlığı değiştirmek için uygulamanın yarısını geçersiz kılmanızın nedeni haline gelir.
Stabil Turbopack: Her gün duyduğunuz kısım
Next.js 16, Turbopack'i geliştirme ve oluşturmanın merkezine getiriyor. Bu en şiirsel özellik değil ama çalışırken hissettiğiniz şey: daha erken başlayan sunucu, daha hızlı yenilenen, zorunlu bir kahve molası hissi vermeyen yapılar.
Bununla birlikte, özel eklentilerle dolu bir kod tabanını gözlerim kapalıyken taşımayacağım. Kontrol edeceğim:
- yerel yapı;
- standart dışı ithalat;
- MDX, SVG ve CSS;
- Web paketi eklentileri kaldı;
- kritik sayfalar;
- yapım sürelerindeki farklılıklar.
Yeni projeler için varsayılandan başlardım. Olgun olanlar için ölçülü bir göç yapardım.
React Compiler: düşünceyi değil gürültüyü kaldırın
React Compiler 1.0 stabildir ve Next.js 16 bunu reactCompiler ile destekler. Söz verilen, manuel notlandırmanın çoğunu azaltmaktır: daha az memo, daha az useMemo, daha az useCallback "güvenlik için" kullanılır.
// next.config.ts import type { NextConfig } from 'next'; const nextConfig: NextConfig = { reactCompiler: true, }; export default nextConfig;
Ona sihirli bir toz gibi davranmayacağım. Derleyici, kodun React kurallarına iyi uyması durumunda yardımcı olur. Bileşenlerin garip yan etkileri, gizli mutasyonları veya kötü kullanılmış kancaları varsa, öncelikle bunun düzeltilmesi gerekir.
Denemenin sağlıklı yolu:
- güncelleme
eslint-plugin-react-hooks; - gerçek ihlalleri düzeltmek;
- kontrollü bir alanda etkinleştirin;
- oluşturma süresini ve davranışını ölçün;
- Manuel notlamayı yalnızca artık ihtiyaç duyulmadığında kaldırın.
Amaç her useMemo'yi silmek değil. Amacımız, render edilmekten korktuğumuz için önleyici not yazmayı bırakmaktır.
proxy.ts ve ağ sınırı
Eski middleware.ts, proxy.ts olur. Bu bir isim değişikliğidir, ancak mantıklıdır: bu dosya istek sınırında yer alır, geleneksel arka uç tarzı genel ara yazılım değildir.
// proxy.ts import { NextRequest, NextResponse } from 'next/server'; export default function proxy(request: NextRequest) { const isLoggedIn = Boolean(request.cookies.get('session')); if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.redirect(new URL('/login', request.url)); } return NextResponse.next(); }
Buradaki kural basit: küçük tutun. Yönlendirme, kimlik doğrulama yönlendirme, başlıklar, temel yeniden yazma işlemleri. İkinci bir arka uç gibi hissetmeye başlarsanız muhtemelen çok fazla şey yapıyordur.
Gerçekten nasıl göç ederdim
Tüm özellikleri aynı anda açmayacağım. Bunu yapardım:
- Sonraki, React ve React DOM'u güncelliyorum;
- Resmi kod modunu başlatıyorum;
params,searchParams,cookies(),headers()vedraftMode()üzerinde bozulan değişiklikleri düzeltiyorum;middleware.ts'ıproxy.ts'e taşıyorum;- Yapıları ve kritik sayfaları kontrol ediyorum;
- Önbelleğin şu anda sürtünme yarattığı bir bölümde Önbellek Bileşenlerini etkinleştiriyorum;
- Etiketler ve geçersiz kılma kurallarını ben tanımlarım;
- React Compiler'ı ayrı ayrı denedim;
- öncesi ve sonrası metriklerin karşılaştırılması.
İyi geçiş, tüm yeni özellikleri kullanan geçiş değildir. Uygulamanın davranışını daha okunabilir kılan şey budur.
Düşünme biçiminde neler değişir?
Next.js 16'nın en faydalı yanı sizi niyetleri daha iyi adlandırmaya zorlamasıdır. Bir fonksiyon sadece "ürünü veri tabanından almak" değildir. "Ürünü alın, saatlerce önbelleğe alabilirim, bu etiketle geçersiz kılarım". Bir bileşen yalnızca "sayfayı oluşturmak" değildir. "Bu hızlı kabuk, bu parça kişisel, bu akışla geliyor."
İlk başta daha fazla iş varmış gibi görünüyor. Daha sonra bu bir tür sakinleşmeye dönüşür. Performans kararları artık varsayılanların, buluşsal yöntemlerin ve kabile hafızasının birleşiminde gizli değil. Kodun içindeler.