Next.js 16.3: وقتی اپ سرور-محورت مثل SPA رفتار میکنه
یه انتقاد قدیمی به Next.js وجود داشته که هرچقدر هم منطقی باشه، همیشه کمی ناراحتکننده بود: وقتی روی یه لینک کلیک میکنی، چیزی نمیشه. صفحه فقط منتظر میمونه تا سرور جواب بده، بعد یهو همه چیز ظاهر میشه. این رفتار برای یه بلاگ یا سایت خبری کاملاً قابل قبوله، ولی برای یه اپ داشبورد یا پروداکتیو، حس میده داری از سایتهای دهه نود استفاده میکنی.
در حالی که SPAها از روز اول همین مشکل رو حل کرده بودن: کلیک میکنی، یه shell از صفحهی بعدی بلافاصله نشون داده میشه — حتی اگه دادهها هنوز دارن لود میشن. این حس «instant» بودن چیزیه که خیلی از توسعهدهندهها رو به سمت SPAها میکشه، حتی وقتی میدونن که مدل سرور-محور Next.js از نظر فنی برتریهای زیادی داره.
۲۵ ژوئن ۲۰۲۶، تیم Next.js یه پیشنمایش از نسخهی ۱۶.۳ منتشر کرد که مستقیماً همین مشکل رو هدف گرفته: Instant Navigations.
ایدهی اصلی چیه
وقتی یه route توی Next.js به دادهای از سرور await میکنه، سه گزینه داری:
Stream با <Suspense>: کاربر بلافاصله یه loading shell میبینه و دادهها بعداً stream میشن. navigation ایمدیت، دادهها دیرتر.
Cache با 'use cache': کاربر یه UI کششدهی قبلی رو میبینه، تا زمانی که نسخهی جدید آماده بشه. باز هم navigation ایمدیت.
Block با export const instant = false: بگی این route نباید instant باشه — مثلاً یه بلاگ که نمیخوای shell خالی صفحهی پست رو نشون بده. navigation منتظر سرور میمونه.
دو گزینهی اول navigation رو به حالت SPA-like در میارن. گزینهی سوم اختیارىه و بهت کنترل میده.
برای فعال کردنش، یه flag توی next.config.ts اضافه میکنی:
const nextConfig: NextConfig = {
cacheComponents: true,
};
این flag قراره در یه major version آینده به حالت default تبدیل بشه.
prefetching رو هم از اول طراحی کردن
یه مشکل دیگه هم وجود داشت که کمتر بهش توجه میشد: حتی اگه سرور سریع جواب بده، هنوز یه رفتوبرگشت شبکه بین client و سرور داری. Next.js قبلاً این مشکل رو با prefetch کردن لینکها حل میکرد — برای هر لینکی که توی viewport بود، یه request جداگانه میزد. اگه یه sidebar با بیست لینک داشتی، بیست request. اگه به Network tab نگاه میکردی، یه طوفان از requestها میدیدی که به گفتهی خود تیم Next.js «مسخره به نظر میرسید».
توی ۱۶.۳ این رویکرد عوض شده: به جای prefetch کردن بهازای هر لینک، حالا یه shell بهازای هر route prefetch میشه. یعنی اگه بیست لینک داری که همه به /chat/[id] اشاره میکنن، فقط یه بار shell اون route دانلود میشه و کش میشه.
برای فعال کردن این رفتار:
const nextConfig: NextConfig = {
cacheComponents: true,
partialPrefetching: true,
};
البته اگه بخوای برای یه لینک خاص بیشتر از shell prefetch بشه — مثلاً header یه صفحهی chat — میتونی با <Link prefetch={true}> opt-in کنی. توی اون حالت هم Next.js فقط تا جایی prefetch میکنه که synchronous یا 'use cache' باشه، نه کل route.
Instant Insights: slow navigation بهعنوان error
چیزی که توی این آپدیت جالبه اینه که تیم Next.js تصمیم گرفته navigationهای کند رو توی development mode بهعنوان error نشون بده — نه warning، error. یه پنل جدید به اسم Instant Insights اضافه شده که بهطور خودکار routeهایی که instant نیستن رو پیدا میکنه و نشون میده.
برای تست هم یه helper اضافه شده:
import { instant } from '@next/playwright';
test('navigation is instant', async ({ page }) => {
await page.goto('/products/shoes');
await instant(page, async () => {
await page.click('a[href="/products/hats"]');
await expect(page.locator('h1')).toContainText('Baseball Cap');
await expect(page.getByText('Checking inventory...')).toBeVisible();
});
});
این یعنی میتونی توی CI هم چک کنی که navigationهای instant بودنشون رو از دست ندادن.
یه Navigation Inspector هم اضافه شده که بهت اجازه میده هر navigation رو «pause» کنی و ببینی shell چه شکلیه، قبل از اینکه دادههای واقعی بیان.
چقدر واقعاً فرق میکنه
تیم Next.js گفته که این feature رو روی v0 — اپ داخلی Vercel — قبل از release استفاده کردن. نتیجهای که منتشر کردن نشون میده که navigation time از چند صد میلیثانیه به نزدیک صفر رسیده برای اکثر routeها، بعد از اینکه کار روی routeهای کند رو تموم کردن.
البته این هنوز preview هست و یه سری محدودیتهای شناختهشده هم وجود داره: بعضی routeهای blocking توی Instant Insights گزارش نمیشن، و tooling توی Safari مشکل داره. تیم گفتن که اینها قبل از stable release برطرف میشن.
چطور امتحانش کنی
npm install next@preview
بعدش cacheComponents: true رو به config اضافه کن و ببین کدوم routeهات blocking هستن. اگه میخوای Partial Prefetching هم باشه، partialPrefetching: true رو هم اضافه کن.
یه دمو هم آماده کردن به اسم Next Beats — یه موزیکپلیر که روی Next.js 16.3 ساخته شده و سورسش هم روی GitHub هست — که میتونی ببینی navigationهای instant در عمل چطور به نظر میرسن.
این مسیری که Next.js داره طی میکنه — گرفتن بهترین چیز SPA (navigation ایمدیت) بدون دادن مزایای server-centric — از نظر فنی جالبه. مشکل اصلی که همیشه بود این بود که مجبور بودی یا همهچیز رو client side بکنی تا instant باشه، یا server side بروی و سرعت navigation رو فدا کنی. حالا دیگه این tradeoff اجباری نیست.