Log in to leave a comment
No posts yet
هناك مشكلة مزمنة كانت تؤرق مطوري الويب؛ وهي ظاهرة التحول القسري لصفحة ثابتة تم بناؤها بعناية إلى رندر ديناميكي (Dynamic Rendering) بالكامل لمجرد استدعاء واحد لـ cookies() أو الوصول إلى الرأس (Headers). اعتمد نظام App Router السابق في Next.js على نموذج ضمني حيث يقرر الإطار العملي عملية التخزين المؤقت (Caching) تلقائيًا. ورغم أن هذا الأسلوب بدا مريحًا، إلا أنه غالبًا ما وضع المطورين في حالة "كل شيء أو لا شيء" (All-or-Nothing)، مما أدى لكسر مزايا التخزين المؤقت لشجرة المكونات بأكملها دون قصد.
لقد تخلص Next.js 16 تمامًا من هذا التفكير الثنائي. الآن، ليس من الضروري تعريف الصفحة بأكملها كصفحة ثابتة أو ديناميكية. لقد بدأ نموذج الرندر المختلط (Hybrid Rendering)، حيث يتعايش داخل الصفحة الواحدة مكونات خادم مخزنة بدقة (المعروفة بـ الخبز - Bread) مع مكونات عميل تتطلب تفاعلاً في الوقت الفعلي (المعروفة بـ الثقوب - Holes). إن فهم هذا التغيير يتجاوز مجرد الفضول التقني، فهو المفتاح العملي لتقليل تكاليف البنية التحتية للخادم وتعظيم نتائج Lighthouse.
التغيير الأكثر ثورية في Next.js 16 هو تحول التخزين المؤقت إلى نظام الاختيار المسبق (Opt-in). لقد ولى عصر ترك كل شيء لتقدير إطار العمل. الآن، يجب على المطور استخدام موجّه use cache صراحةً لتحديد التخزين المؤقت على مستوى الدوال أو المكونات.
أولاً، يجب تفعيل الميزة التجريبية في ملف next.config.ts.
typescript // next.config.ts const nextConfig = { experimental: { dynamicIO: true, // تفعيل الرندر المختلط و use cache }, }
يمكن الإعلان عن موجّه use cache في أعلى الملف، أو داخل المكون، أو حتى داخل دالة غير متزامنة محددة. من خلال ذلك، يمكن تعظيم كفاءة الرندر المسبق الجزئي (PPR) لتقليل وقت الاستجابة الأول (TTFB) بنسبة تتراوح بين 60 إلى 80%. التغييرات الطفيفة في البيانات التي كانت تتطلب سابقًا إعادة رسم الصفحة بالكامل، تتم معالجتها الآن فقط داخل حدود ذاكرة تخزين مؤقت محددة.
يجب أن يكون منطق جلب البيانات في أقرب مكان ممكن من المكونات التي تستخدمها، وهو ما يسمى بـ تجميع البيانات (Data Colocation). إن أسلوب جلب كافة البيانات في التخطيط العلوي (Layout) وتوزيعها على الأبناء يزيد من درجة الاقتران بين المكونات ويجعل الصيانة جحيمًا.
يحل Next.js 16 هذه المشكلة من خلال الجمع بين React.cache وخطاف use. وبفضل مذكرة الطلبات (Request Memoization) التي تمنع الطلبات المكررة داخل نفس مسار الرندر، سيتم تنفيذ طلب الشبكة مرة واحدة فقط حتى لو قامت مكونات متعددة باستدعاء نفس واجهة البرمجة (API).
استغلال هذه الاستراتيجية يمكن أن يقلل كمية جافا سكريبت في جانب العميل بنسبة تصل إلى 70-80%. وبما أن البيانات تُعالج مسبقًا في الخادم ويتم تمرير النتائج فقط، فلا يحتاج العميل لتحمل عبء المنطق الثقيل.
نمط الدونات هو نموذج يفصل ويجمع بوضوح بين الأجزاء الثابتة (الدونات) والأجزاء الديناميكية (الثقب).
use cache. تقوم بجلب البيانات ومعالجة المنطق الثقيل وتخزين النتائج مؤقتًا.جوهر هذا النمط يكمن في هيكلية استقبال مكون الخادم لمكون العميل كخاصية children للرندر. حتى لو تم تخزين مكون الخادم (الأب) مؤقتًا، تظل عناصر العميل (الأبناء) تعمل بدورة حياة مستقلة.
useState أو useEffect إلى أصغر وحدة ممكنة من مكونات العميل.use cache في مكون الخادم الأب وإجراء استعلامات قاعدة البيانات.children بدلاً من استيراده مباشرة.Suspense لضمان رندر الغلاف الثابت فورًا.إذا كانت الصفحة لا تزال بطيئة أو تعمل بشكل ديناميكي رغم تطبيق use cache فعليك الشك في تسرب واجهة البرمجة الديناميكية (Dynamic API Leak). إذا تم استدعاء cookies() أو headers() داخل حدود التخزين المؤقت، فسيتحول ذلك النطاق فورًا إلى الرندر الديناميكي. يجب تحسين الهيكل بتمرير هذه القيم كوسطاء بدلاً من استدعائها مباشرة.
علاوة على ذلك، يجب أن يكون كل وصول للبيانات غير المتزامنة داخل Suspense. وإلا، سيقوم إطار العمل بإلقاء خطأ يفيد بالوصول إلى بيانات غير مخزنة مؤقتًا وسيتخلى عن التوليد الثابت.
أرقام تحسن الأداء في معمارية Next.js 16 واضحة:
| مؤشر الأداء | تفاصيل التحسين | التأثير المتوقع |
|---|---|---|
| TTFB (وقت أول بايت) | تقليل بنسبة 60-80% عند تطبيق PPR و use cache |
تقليل جذري في وقت انتظار استجابة الخادم |
| TBT (إجمالي وقت الحظر) | تقليل استحواذ الخيط الرئيسي عبر استراتيجية تأجيل السكريبت | تحسين استجابة مدخلات المستخدم |
| Build Time (وقت البناء) | تقليص الوقت بمقدار 2-5 مرات بفضل Turbopack | زيادة إنتاجية التطوير وسرعة النشر |
إذا كنت تعمل في بيئة خارج Vercel (مثل Docker)، فمن الضروري استخدام محول ذاكرة تخزين مؤقت Redis. يتيح ذلك لآلاف مثيلات الخادم مشاركة مستودع تخزين مؤقت مركزي واحد، مما يقلل العبء على قاعدة البيانات.
لم يعد Next.js 16 يجبر المطورين على الاختيار بين الثابت والديناميكي. الآن، تعتمد قدرة تصميم المعمارية على مدى دقة نسج هذين العالمين معًا.
على المطور الذكي أن يبدأ بتحديد الصفحات التي تحولت بالكامل للديناميكية بسبب الإسراط في استخدام cookies(). بعد ذلك، قم بنقل منطق جلب البيانات إلى المكونات الفرعية لزيادة الاستقلالية، وقلل من تأثير المكتبات الثقيلة عبر use cache ونمط الدونات. في اللحظة التي ترى فيها صفحتك تظهر كـ Static أو PPR في تقرير البناء، فاعلم أنك قد وضعت حجر الأساس لخدمة مستدامة وعالية الأداء.