المقدمة

كثير من المطورين اللي بيشتغلوا بـ Next.js بيواجهوا مشكلة محيرة؛ ممكن تعدل في البيانات الخاصة بالموقع بتاعك، وفي الآخر تلاقي إن التغييرات مش بتظهر على طول أو بتظهر بعد وقت طويل. المشكلة دي بتكون غالبًا نتيجة آليات ال cache الليNext.js بيستخدمها ، واللي فهمك ليها كويس هيخليك قادر انك تحسن من ال performance وكمان ال  . Development experience.في المقال ده هنتكلم عن Next js caching mechanisms  وهما:

  1. Request Memoization
  2. Data Cache
  3. Full Route Cache
  4. Router Cache

Request Memoization

الـ Request Memoization في Next.js بتشتغل على تخزين نتيجة الrequests اللي ليها نفس الـ URL وال options. يعني بدل ما التطبيق يعمل request للبيانات في كل مكان، هيعمل request واحد ويبقى عامل memoize للنتيجة، وكل الcomponents الخاصة بال page او ال route اللي محتاجه البيانات هتستفاد من الcache ده.- مثال عشان الموضوع يوضح بشكل أكبر- لنفترض إنك عندك e-commerce  وعندك صفحة بتعرض كل منتج, هنا عشان تحسن ال SEO  محتاج إنك تظبط ال meta data الخاصة بالصفحة بتاعتك فهتبدأ إنك تعمل fetch  للداتا الخاصة بالمنتج عشان ال title  وال meta description علي سبيل المثال .

  • ثاني حاجة هتحتاج تعمل request تاني بداخل الpage عشان تعرض الداتا الخاصة بالمنتج , وهنا تأتي أهمية ال request memoization إنه بعد أو request هيعمل cache للبيانات بحيث أي component في ال page  هيستخدم نفس الrequest هياخد الداتا من الcache بدل ما يتم request جديد ,مثال:
async function fetchProductData(productId) {
   const res = await fetch(`https://example.com/api/products/${productId}`);
   return res.json();
}


export async function generateMetadata({ params }) {
   const { name } = await fetchProductData(params.productId);
   return { title: `Product ${name}` };
}
export default async function Page({ params }) {
  const {name} = await fetchProductData(params.productId);
  return <div>
      <h1>{name}</h1>
  </div>;
}

الـ Revalidating : الآلية دي مش محتاجة revalidating لإنها شغالة خلال دورة حياة صفحة واحدة (single page render).

الـ Opting Out : لو عايز تلغي الcache، ممكن تستخدم AbortController لإلغاء التخزين المؤقت


Data Cache

بشكل افتراضي، Next.js بتخزن البيانات التي يتم جلبها عبر استخدام "fetch", وده لأن Next.js قامت بعمل extend لل native fetch api عشان تسمح إن كل request يكون ليه caching semantics خاصة بيه والقيمة الافتراضية لخاصية ال cache  تكون force-cache

طيب الdata cache بيشتغل ازاي؟

  1. بيشوف الأول هل في نسخة من البيانات التي طلبتها ولا لأ
  2. لو في بيانات مٌخزنة بيرجعها فورًا
  3. لو مفيش بيعمل request وبيخزن البيانات بحيث لو تم فيما بعد أي  request يبدأ
    إنه ياخد البيانات من الcache

مثال علي استخدام ال data cache :

const response = await fetch("https://api.example.com/data", {
   cache: "no-store", // إيقاف التخزين المؤقت
});

عندنا نوعين لل revalidating وهما: 

1- Time-based: وده عن طريق إنك بتحدث البيانات بعد وقت معين ومثال علي هذا:

const response = await fetch("https://example.com/api/data", {
   next: { revalidate: 3600 },
});

2- On-demand: وده عن طريق إنك بتحدث البيانات بعد حدث معين زي إنك تبعت فورم معينة ومثال علي كدا:revalidatePath('/')

  • Opting out

وده بيتم عن طريق إنك تضع القيمة 0 في خاصية ال revalidate أو إنك تستخدم “no store” مثل هذا المثال 

const response = await fetch("https://example.com/api/data", {
   cache: "no-store", });

Full Route Cache

عندنا Next.js بيعمل caching للroutes أثناء generation علشان يسرع تحميل الصفحات ويقلل الضغط على السيرفر.

إزاي بيشتغل Full Route Cache؟

  1. لو الصفحة static (محتواها ثابت زي صفحة "تواصل معنا") Next.js بيبني الصفحة مرة واحدة وقت الـ Build وبيخزنها. وأي حد يدخل عليها بعد كده هياخد النسخة المخزنة مباشرة.
  2. لو الصفحة dynamic (محتواها بيتغير زي صفحة عرض منتج) ممكن تستخدم تقنية اسمها ISR (Incremental Static Regeneration). في البداية، الصفحة بتتولد وتتخزن، وبعد كده بتتجدد بشكل دوري (زي كل ساعة) أو لما يحصل تغيير في البيانات
  • Revalidating 

- وبالنسبة ال revalidating فا بيتم لما بيحصل revalidate لل data cache او لما بيحصل Redeploying

- وكذلك ال opt out بيتم لما بيحصل revalidate لل data cache او تستخدم dynamic = 'force-dynamic' or revalidate = 0


Router Cache

دي آلية بتخزن الصفحات اللي تم زيارتها مسبقًا أو تم جلبها مسبقًا (Prefetched) في ذاكرة المتصفح. سواء كانت الصفحات ثابتة (Static) أو ديناميكية (Dynamic)، بيتم تخزينها لمدة معينة.

فوائد هذه الآلية:

  1. تجربة تشبه تطبيقات الصفحة الواحدة (SPA): التنقل بين الصفحات بيكون سريع وسلس، من غير ما تضطر تعيد تحميل الصفحة بالكامل.
  2. تقليل عدد ال requests: بما أن الصفحات المخزنة مش بتحتاج requests جديدة عند التنقل بينها، ده بيساعد في تقليل الحمل على السيرفر

وطبعا لايوجد شىء لا يخلو من العيوب ومن ضمن عيوب هذه الآلية التالي:

  1. البيانات القديمة: ممكن البيانات المعروضة تكون قديمة لو مفيش تحديث من الخادم
  2. فترة التخزين: الصفحات الثابتة بتتخزن لمدة 5 دقائق، في حين أن الصفحات الديناميكية بتتخزن لمدة 30 ثانية فقط.