ناوبری فوری یک قرارداد محصول است، نه یک تنظیم prefetch
بیشتر کار «سرعت ناوبری» را میشود جعل کرد. یک اسپینر، چند لینک با prefetch، یک Lighthouse روی صفحه فرود، و بعد برچسب سریع. مشتری از فهرست به جزئیات میرود، روی اتصال متوسط، و همان یک کوئری که واقعاً مهم است او را نگه میدارد.
Next.js 16.3 از این جهت جالب است که این آرزوی مبهم را به چیزی نزدیک به قرارداد مهندسی تبدیل میکند. کار Instant Navigations از مسیر میخواهد صریح باشد: میتواند استریم کند، میتواند داده کششده بدهد، یا میتواند عمداً بلوکه کند. وقتی مسیر را میشود فوری کرد، فریمورک پوسته را prefetch میکند و دوباره استفاده میکند. وقتی نمیشود، تیم باید مالک آن تصمیم باشد. کمکتابع تست `instant()` هم برای گرفتن رگرسیون هست.
این از یک قول دیگر «حس SPA» مفیدتر است. تغییر واقعی این است که معماری مسیر قابل مشاهده و قابل تست میشود. اگر هنوز روی نسخهای هستی که این مسیر پشت Cache Components و partial prefetch است و یادداشت انتشار مسئله شناختهشده دارد، آن را پیشنمایش جدی بدان نه دستور بازنویسی کل اپ. شاخه و یک مسیر پرتکرار کافی است.
کلیک سریع با داده تازه یکی نیست
مدل، جدایی را ملموس میکند. پوسته قابل استفاده مجدد میتواند لحظه کلیک دیده شود و ناحیه دینامیک کوچکتر بعداً استریم شود. دادهای که واقعاً پایدار است کش میشود. مسیری که باید صبر کند، صریحاً از فوری بودن خارج میشود و بلوکه میکند.
هیچکدام از این قطعات در انتزاع تازه نیستند. Suspense، استریم، و مرز کش از قبل بودند. ارزش این است که قطعات دور یک نتیجه قابل مشاهده ردیف شوند: آیا کاربر مقصد معنیدار را فوراً گرفت؟
عبارت مهم است. یک فریم خالی با نوار بالا از نظر فنی پوسته است، ولی لزوماً مفید نیست. پوسته باید بگوید کاربر کجا فرود آمده: عنوان، چیدمان، وضعیت ناوبری، قاب تصویر، جای قیمت، شکل جدول، یا بدنه ویرایشگر. باید عدمقطعیت را کم کند، نه اینکه اسپینر را به کلیک نزدیکتر کند.
از آناتومی مسیر شروع کن، نه از تنظیم
وسوسه این است که Cache Components و prefetch جزئی را روشن کنی و منتظر پاداش فریمورک بمانی. من از جای کمزرقوبرقتر شروع میکنم. سه مسیری را که آدمها بیشتر بینشان میروند انتخاب کن و آناتومیشان را بکش.
برای هر مسیر چهار چیز را نام ببر. اطلاعاتی که لحظه کلیک باید دیده شود وگرنه صفحه معنی ندارد. دادهای که یک لحظه دیرتر میتواند بیاید بدون اینکه اعتماد خراب شود. درخواستی که رندر زودهنگام را واقعاً غیرممکن میکند. مرز کش یا باطلسازی برای هر تکه پایدار.
صفحه جزئیات محصول را در نظر بگیر. ناوبری، عنوان، قاب رسانه، گونه انتخابشده، و کنترل خرید معمولاً برای تثبیت مقصد کافیاند. موجودی، برآورد ارسال، نظرها، پیشنهادها، و صلاحیت تخفیف شخصی ممکن است کندتر باشند. اینها فقط به این دلیل که صفحه بالاخره همهشان را میخواهد نباید داخل یک Server Component غول باشند.
این استدلال برای نشان دادن عدد کهنه نیست. برای دقیق بودن است درباره اینکه کدام عدد یک عمل را ناامن میکند. اگر کنترل، تعهد مالی میسازد، باید برای وضعیت معتبر صبر کند. اگر فهرست رویداد اخیر فقط زمینه است، میتواند استریم شود. اینها اول تصمیم محصولاند، دوم تصمیم کش.
تست باید بگوید چه چیزی اجازه دارد دیر برسد
قویترین بخش این کار، `instant()` است چون تیم میتواند تصمیم را در تست بنویسد. تست ناوبری خوب فقط نمیگوید «URL عوض شد». میگوید چه چیزی فوراً ظاهر میشود و چه چیزی مجاز است دیرتر برسد.
مثلاً برای `/projects/[id]` میتوانی بخواهی عنوان، نانریزه، و نوار تب بدون انتظار دیده شوند. بعد بگویی نمودار مصرف تا قبل از resolve یک حالت بارگذاری عمدی نشان دهد. اگر بازنویسی بعدی، خواندن پروژه را زیر یک مرز والدِ کشنشده ببرد، تست باید بشکند حتی اگر صفحه نهایی دو ثانیه بعد درست به نظر برسد.
این رگرسیون آشنا را میگیرد: کسی یک وابستگی بهظاهر بیگناه به layout اضافه میکند. خواندن احراز هویت وابسته به درخواست، تخصیص آزمایش، یا خواندن locale. شکل رندر عوض میشود، prefetch دیگر پوسته قابل استفاده نمیسازد، و کسی متوجه نمیشود چون اتصال محلیاش سریع است.
تست را باریک نگه دار. هر مسیر را به بنچمارک شکننده با آستانه زمانی تبدیل نکن. ترتیب رسیدن و پوسته معنیدار را assert کن. محدود کردن شبکه یا زمان مصنوعی را فقط وقتی شکست را بررسی میکنی به کار ببر. ناوردای پایدار این است که «این بخش مسیر نباید منتظر آن وابستگی بماند»، نه اینکه «کلیک در CI باید در فلان میلیثانیه تمام شود».
prefetch بودجه دارد
prefetch جزئی جذاب است چون برای حس پاسخگویی، کل صفحه آینده را نمیکشد. برای مسیر فوری، پوسته قابل استفاده مجدد یکبار گرفته و کش میشود. مرورگر قبل از کلیک کار مفید دارد، بدون اینکه وانمود کنی هر مقصد ممکن مجانی است.
با این حال prefetch فضیلت اخلاقی نیست. در ادمین شلوغ، prefetch مشتاق هر ردیف، پهنا و حافظه را صرف صفحههایی میکند که کاربر بازشان نمیکند. در سایت محتوایی عمومی، پوسته مقاله محتمل بعدی منطقی است. گرم کردن هر مقاله مرتبط معمولاً نه. روی موبایل این هزینه از چشم توسعهدهنده راحتتر پنهان میشود و برای بازدیدکننده سختتر قابل دفاع است.
سیاست را صریح کن. ناوبری را prefetch کن که مسیر نیت روشن دارد: فهرست جاری، عمل اصلیِ در دید، قدم بعدی تسویه، تب فعال فضای کار. برای مجموعه بیکران، منوی شلوغ مبتنی بر hover، و پیشنهاد حدسی، prefetch خودکار نگذار. قبل از جشن دموی کلیک اول، اندازه انتقال و حافظه کلاینت را ببین.
با استریم از مرز بد فرار نکن
استریم دریچه فرار قوی است و برای همین سوءاستفادهاش آسان است. صفحههایی را دیدهام که به خاطر عدد بهتر داشبورد به دوازده مرز Suspense تکهتکه شدهاند. نتیجه صفحهای بوده که به ترتیب تصادفی جمع میشده، چیدمان را جابهجا میکرده، و کاربر را به شک میانداخته که داده خراب است.
قانون مفید: در امتداد مرز محصول استریم کن، نه مرز fetch. «پنل فعالیت در حال بارگذاری است» قابل فهم است. «جمع دوم کارت چهارم هنوز نیامده ولی برچسب و آیکون هست» معمولاً نویز بصری است. اطلاعات وابسته را گروه کن، برای محتوای دیر جا نگه دار، و به هر حالت بارگذاری شغلی بده که آدم بفهمد.
موانع پنهان را هم ببین. خواندن params، کوکی، هدر، یا وضعیت پیشنویس در جای غلط درخت، پوسته را به کار زمان درخواست وابسته میکند. یک fetch کشنشده در layout مشترک میتواند ناوبری یک بخش را مسموم کند. لایه شخصیسازی سراسری گاهی از خود صفحهای که شخصی میکند گرانتر است. Navigation Inspector کمک میکند، ولی مرور درخت مسیر در خود کد هنوز لازم است.
پذیرش عاقلانه
همه مسیرهای پروداکشن را یکشبه بازچین نکن. یک مسیر را که مردم واقعاً بین دو صفحهاش میروند انتخاب کن. پوسته را نام ببر. داده دیر را نام ببر. مانع واقعی را نام ببر. یک تست بنویس که ترتیب را قفل کند نه میلیثانیه را. prefetch را فقط روی نیت روشن بگذار. اگر این مسیر بعد از یک وابستگی بیگناه در layout دیگر فوری نبود، قبل از پخش الگو به بقیه سایت، مرز را درست کن.
پرسشهای کوتاه
همه صفحهها باید instant باشند؟ نه. صفحهای که بدون داده معتبر عمل خطرناک میسازد باید بلوکه کند و این را صریح بگوید. فوری بودن برای جایی است که پوسته معنیدار بدون آن داده ممکن است.
Suspense بیشتر یعنی سریعتر؟ نه لزوماً. استریم در مرز محصول به اعتماد کمک میکند. استریم در مرز هر fetch اغلب صفحه را تکهتکه و نامطمئن نشان میدهد.
آستانه میلیثانیه در CI بگذارم؟ برای قرارداد ناوبری نه. آن عدد روی ماشین CI دروغ میگوید. چیزی را قفل کن که نباید منتظر وابستگی مشخص بماند.