وصل Next.js 15 ببعض التغييرات الحاسمة — واجهات طلب غير متزامنة (async)، وإعدادات تخزين مؤقت افتراضية أكثر صرامة، وانتقال Turbopack إلى مرحلة الاستقرار. وقد شغّلناه في الإنتاج لمدة ستة أشهر عبر ثلاثة مشاريع لعملاء. وإليك النسخة بلا تنميق.
نموذج التخزين المؤقت أصبح أخيرًا منطقيًا
أكبر تحوّل ذهني في App Router هو الانتقال من تفكير getStaticProps / getServerSideProps إلى قرارات تخزين مؤقت لكل عملية جلب (fetch). في Next.js 15، لا تُخزَّن عمليات الجلب مؤقتًا افتراضيًا. أنت من يختار تفعيلها.
// مُخزَّن مؤقتًا، يُعاد التحقّق منه كل 60 ثانية
const data = await fetch('/api/data', { next: { revalidate: 60 } })
// طازج دائمًا (مثل getServerSideProps)
const data = await fetch('/api/data', { cache: 'no-store' })
// مُخزَّن مؤقتًا إلى أجل غير مسمّى (مثل getStaticProps)
const data = await fetch('/api/data', { cache: 'force-cache' })
هذا أكثر وضوحًا وأقل سحرية من النموذج السابق. وقد توقّفنا عن اللجوء إلى unstable_cache في معظم الحالات.
Turbopack حقيقي الآن
التطوير المحلّي مع Turbopack أسرع بشكل ملحوظ في المشاريع الكبيرة. تطبيق أكبر عملائنا — أكثر من 200 مسار وأكثر من 400 مكوّن — انتقل من 8 ثوانٍ لبدء التشغيل البارد إلى أقل من 2. وإعادة التحميل السريع (hot reload) فورية.
لم نصطدم بأي مشكلة توافق في Turbopack منذ ثلاثة أشهر. اعتمدوه.
ما كنّا سنفعله بشكل مختلف
ندم واحد: وضعنا الكثير من المنطق داخل Server Components في وقت مبكّر. وقد صار بعض ذلك صعب الاختبار الآن. القاعدة التي نستخدمها الآن: مكوّنات الخادم (Server Components) تجلب البيانات وتمرّرها إلى الأسفل. ومكوّنات العميل (Client Components) تتولّى التفاعل. أمّا المنطق فيعيش في دوال عادية لا يعرف أيٌّ منهما عنها شيئًا.
