التخزين المؤقت في Next.js
يحسن Next.js أداء تطبيقك ويقلل التكاليف من خلال تخزين أعمال التصيير وطلبات البيانات مؤقتًا. توفر هذه الصفحة نظرة متعمقة على آليات التخزين المؤقت في Next.js، وواجهات برمجة التطبيقات (APIs) التي يمكنك استخدامها لتكوينها، وكيفية تفاعلها مع بعضها البعض.
معلومة مفيدة: تساعدك هذه الصفحة على فهم كيفية عمل Next.js تحت الغطاء، لكنها ليست معرفة أساسية لتكون منتجًا باستخدام Next.js. يتم تحديد معظم استدلالات التخزين المؤقت في Next.js من خلال استخدامك لواجهات برمجة التطبيقات ولها إعدادات افتراضية لأفضل أداء مع تكوين صفري أو ضئيل.
نظرة عامة
إليك نظرة عامة عالية المستوى على آليات التخزين المؤقت المختلفة والغرض منها:
الآلية | ماذا تخزن | أين | الغرض | المدة |
---|---|---|---|---|
تخزين الطلبات مؤقتًا | قيم الإرجاع للدوال | الخادم | إعادة استخدام البيانات في شجرة مكونات React | دورة حياة الطلب الواحد |
ذاكرة البيانات المؤقتة | البيانات | الخادم | تخزين البيانات عبر طلبات المستخدم والنشرات | مستمر (يمكن إعادة التحقق منه) |
ذاكرة المسار الكامل المؤقتة | HTML وحمولة RSC | الخادم | تقليل تكلفة التصيير وتحسين الأداء | مستمر (يمكن إعادة التحقق منه) |
ذاكرة الموجه المؤقتة | حمولة RSC | العميل | تقليل طلبات الخادم أثناء التنقل | جلسة المستخدم أو بناءً على الوقت |
بشكل افتراضي، سيخزن Next.js أكبر قدر ممكن لتحسين الأداء وتقليل التكلفة. وهذا يعني أن المسارات تُصَيَّر بشكل ثابت وطلبات البيانات مخزنة مؤقتًا إلا إذا اخترت عدم ذلك. يوضح الرسم البياني أدناه سلوك التخزين المؤقت الافتراضي: عندما يتم تصيير مسار بشكل ثابت في وقت البناء وعند زيارة مسار ثابت لأول مرة.

يتغير سلوك التخزين المؤقت اعتمادًا على ما إذا كان المسار يُصَيَّر بشكل ثابت أو ديناميكي، وما إذا كانت البيانات مخزنة مؤقتًا أم لا، وما إذا كان الطلب جزءًا من زيارة أولية أو تنقل لاحق. اعتمادًا على حالة الاستخدام، يمكنك تكوين سلوك التخزين المؤقت للمسارات الفردية وطلبات البيانات.
تخزين الطلبات مؤقتًا
يمتد React لواجهة برمجة التطبيقات fetch
لتخزين الطلبات التي لها نفس URL والخيارات تلقائيًا مؤقتًا. وهذا يعني أنه يمكنك استدعاء دالة fetch لنفس البيانات في أماكن متعددة في شجرة مكونات React مع تنفيذها مرة واحدة فقط.

على سبيل المثال، إذا كنت بحاجة إلى استخدام نفس البيانات عبر مسار (مثل في Layout وصفحة ومكونات متعددة)، فلا يتعين عليك جلب البيانات في أعلى الشجرة ثم تمرير الخصائص بين المكونات. بدلاً من ذلك، يمكنك جلب البيانات في المكونات التي تحتاجها دون القلق بشأن الآثار المترتبة على الأداء لإنشاء طلبات متعددة عبر الشبكة لنفس البيانات.
async function getItem() {
// يتم تخزين دالة `fetch` تلقائيًا مؤقتًا وتخزين النتيجة
const res = await fetch('https://.../item/1')
return res.json()
}
// يتم استدعاء هذه الدالة مرتين، ولكن يتم تنفيذها فقط في المرة الأولى
const item = await getItem() // cache MISS
// يمكن أن يكون الاستدعاء الثاني في أي مكان في مسارك
const item = await getItem() // cache HIT
async function getItem() {
// يتم تخزين دالة `fetch` تلقائيًا مؤقتًا وتخزين النتيجة
const res = await fetch('https://.../item/1')
return res.json()
}
// يتم استدعاء هذه الدالة مرتين، ولكن يتم تنفيذها فقط في المرة الأولى
const item = await getItem() // cache MISS
// يمكن أن يكون الاستدعاء الثاني في أي مكان في مسارك
const item = await getItem() // cache HIT
كيف يعمل تخزين الطلبات مؤقتًا

- أثناء تصيير مسار، في المرة الأولى التي يتم فيها استدعاء طلب معين، لن تكون نتيجته في الذاكرة وسيكون cache
MISS
. - لذلك، سيتم تنفيذ الدالة، وسيتم جلب البيانات من المصدر الخارجي، وسيتم تخزين النتيجة في الذاكرة.
- سيؤدي استدعاء الدالة اللاحق لنفس الطلب في نفس تمرير التصيير إلى cache
HIT
، وسيتم إرجاع البيانات من الذاكرة دون تنفيذ الدالة. - بمجرد اكتمال تصيير المسار وتمرير التصيير، يتم "إعادة تعيين" الذاكرة ومسح جميع إدخالات تخزين الطلبات مؤقتًا.
معلومة مفيدة:
- تخزين الطلبات مؤقتًا هو ميزة React وليست ميزة Next.js. تم تضمينها هنا لإظهار كيفية تفاعلها مع آليات التخزين المؤقت الأخرى.
- ينطبق التخزين المؤقت فقط على طريقة
GET
في طلباتfetch
.- ينطبق التخزين المؤقت فقط على شجرة مكونات React، وهذا يعني:
- ينطبق على طلبات
fetch
فيgenerateMetadata
وgenerateStaticParams
وLayouts وPages ومكونات الخادم الأخرى.- لا ينطبق على طلبات
fetch
في Route Handlers لأنها ليست جزءًا من شجرة مكونات React.- للحالات التي لا يكون فيها
fetch
مناسبًا (مثل بعض عملاء قواعد البيانات أو عملاء CMS أو عملاء GraphQL)، يمكنك استخدام دالةcache
في React لتخزين الدوال مؤقتًا.
المدة
يستمر التخزين المؤقت طوال فترة حياة طلب الخادم حتى تنتهي شجرة مكونات React من التصيير.
إعادة التحقق
نظرًا لأن التخزين المؤقت غير مشترك عبر طلبات الخادم وينطبق فقط أثناء التصيير، فلا حاجة لإعادة التحقق منه.
عدم المشاركة
لعدم المشاركة في التخزين المؤقت لطلبات fetch
، يمكنك تمرير signal
من AbortController
إلى الطلب.
const { signal } = new AbortController()
fetch(url, { signal })
ذاكرة البيانات المؤقتة
يحتوي Next.js على ذاكرة بيانات مدمجة تخزن نتائج جلب البيانات عبر طلبات الخادم الواردة والنشرات. وهذا ممكن لأن Next.js يمتد واجهة برمجة التطبيقات fetch
الأصلية للسماح لكل طلب على الخادم بتعيين دلالات التخزين المؤقت الخاصة به.
معلومة مفيدة: في المتصفح، يشير خيار
cache
فيfetch
إلى كيفية تفاعل الطلب مع ذاكرة HTTP للمتصفح، في Next.js، يشير خيارcache
إلى كيفية تفاعل طلب الخادم مع ذاكرة البيانات على الخادم.
بشكل افتراضي، يتم تخزين طلبات البيانات التي تستخدم fetch
مؤقتًا. يمكنك استخدام خيارات cache
وnext.revalidate
في fetch
لتكوين سلوك التخزين المؤقت.
كيف تعمل ذاكرة البيانات المؤقتة

- في المرة الأولى التي يتم فيها استدعاء طلب
fetch
أثناء التصيير، يتحقق Next.js من ذاكرة البيانات المؤقتة للحصول على استجابة مخزنة مؤقتًا. - إذا تم العثور على استجابة مخزنة مؤقتًا، يتم إرجاعها على الفور وتخزينها مؤقتًا.
- إذا لم يتم العثور على استجابة مخزنة مؤقتًا، يتم إجراء الطلب إلى مصدر البيانات، وتخزين النتيجة في ذاكرة البيانات المؤقتة، وتخزينها مؤقتًا.
- بالنسبة للبيانات غير المخزنة مؤقتًا (مثل
{ cache: 'no-store' }
)، يتم دائمًا جلب النتيجة من مصدر البيانات، وتخزينها مؤقتًا. - سواء كانت البيانات مخزنة مؤقتًا أم لا، يتم دائمًا تخزين الطلبات مؤقتًا لتجنب إنشاء طلبات مكررة لنفس البيانات أثناء تمرير تصيير React.
الاختلافات بين ذاكرة البيانات المؤقتة وتخزين الطلبات مؤقتًا
بينما تساعد كلتا آليتي التخزين المؤقت في تحسين الأداء من خلال إعادة استخدام البيانات المخزنة مؤقتًا، فإن ذاكرة البيانات المؤقتة مستمرة عبر الطلبات الواردة والنشرات، بينما يستمر التخزين المؤقت فقط طوال فترة حياة الطلب.
مع التخزين المؤقت، نقلل عدد الطلبات المكررة في نفس تمرير التصيير التي يجب أن تعبر حدود الشبكة من خادم التصيير إلى خادم ذاكرة البيانات المؤقتة (مثل CDN أو شبكة Edge) أو مصدر البيانات (مثل قاعدة بيانات أو CMS). مع ذاكرة البيانات المؤقتة، نقلل عدد الطلبات الموجهة إلى مصدر البيانات الأصلي.
المدة
ذاكرة البيانات المؤقتة مستمرة عبر الطلبات الواردة والنشرات ما لم تقم بإعادة التحقق أو عدم المشاركة.
إعادة التحقق
يمكن إعادة التحقق من البيانات المخزنة مؤقتًا بطريقتين، باستخدام:
- إعادة التحقق بناءً على الوقت: إعادة التحقق من البيانات بعد مرور فترة زمنية معينة وإجراء طلب جديد. هذا مفيد للبيانات التي تتغير بشكل غير متكرر وليست الحداثة فيها بالغة الأهمية.
- إعادة التحقق عند الطلب: إعادة التحقق من البيانات بناءً على حدث (مثل إرسال نموذج). يمكن أن تستخدم إعادة التحقق عند الطلب نهجًا يعتمد على العلامات أو المسار لإعادة التحقق من مجموعات البيانات دفعة واحدة. هذا مفيد عندما تريد التأكد من عرض أحدث البيانات في أسرع وقت ممكن (مثل عند تحديث المحتوى من نظام إدارة المحتوى الخاص بك).
إعادة التحقق بناءً على الوقت
لإعادة التحقق من البيانات على فترات زمنية، يمكنك استخدام خيار next.revalidate
في fetch
لتعيين عمر ذاكرة التخزين المؤقت للمورد (بالثواني).
// إعادة التحقق على الأكثر كل ساعة
fetch('https://...', { next: { revalidate: 3600 } })
بدلاً من ذلك، يمكنك استخدام خيارات تكوين قطاع المسار لتكوين جميع طلبات fetch
في قطاع أو للحالات التي لا يمكنك فيها استخدام fetch
.
كيف تعمل إعادة التحقق بناءً على الوقت

- في المرة الأولى التي يتم فيها استدعاء طلب fetch مع
revalidate
، سيتم جلب البيانات من مصدر البيانات الخارجي وتخزينها في ذاكرة البيانات المؤقتة. - أي طلبات يتم استدعاؤها خلال الإطار الزمني المحدد (مثل 60 ثانية) سترجع البيانات المخزنة مؤقتًا.
- بعد الإطار الزمني، سيظل الطلب التالي يرجع البيانات المخزنة (القديمة الآن) مؤقتًا.
- سيؤدي Next.js إلى إعادة التحقق من البيانات في الخلفية.
- بمجرد جلب البيانات بنجاح، سيحدث Next.js ذاكرة البيانات المؤقتة بالبيانات الجديدة.
- إذا فشلت إعادة التحقق في الخلفية، سيتم الاحتفاظ بالبيانات السابقة دون تغيير.
هذا مشابه لسلوك stale-while-revalidate.
إعادة التحقق عند الطلب
يمكن إعادة التحقق من البيانات عند الطلب عن طريق المسار (revalidatePath
) أو عن طريق علامة ذاكرة التخزين المؤقت (revalidateTag
).
كيف تعمل إعادة التحقق عند الطلب

- في المرة الأولى التي يتم فيها استدعاء طلب
fetch
، سيتم جلب البيانات من مصدر البيانات الخارجي وتخزينها في ذاكرة البيانات المؤقتة. - عند تشغيل إعادة التحقق عند الطلب، سيتم مسح إدخالات ذاكرة التخزين المؤقت المناسبة من الذاكرة.
- يختلف هذا عن إعادة التحقق بناءً على الوقت، التي تحتفظ بالبيانات القديمة في الذاكرة حتى يتم جلب البيانات الجديدة.
- في المرة التالية التي يتم فيها إجراء طلب، سيكون مرة أخرى cache
MISS
، وسيتم جلب البيانات من مصدر البيانات الخارجي وتخزينها في ذاكرة البيانات المؤقتة.
عدم المشاركة
لطلبات جلب البيانات الفردية، يمكنك عدم المشاركة في التخزين المؤقت عن طريق تعيين خيار cache
إلى no-store
. وهذا يعني أنه سيتم جلب البيانات كلما تم استدعاء fetch
.
// عدم المشاركة في التخزين المؤقت لطلب `fetch` فردي
fetch(`https://...`, { cache: 'no-store' })
بدلاً من ذلك، يمكنك أيضًا استخدام خيارات تكوين قطاع المسار لعدم المشاركة في التخزين المؤقت لقطاع مسار معين. سيؤثر هذا على جميع طلبات البيانات في قطاع المسار، بما في ذلك مكتبات الطرف الثالث.
// عدم المشاركة في التخزين المؤقت لجميع طلبات البيانات في قطاع المسار
export const dynamic = 'force-dynamic'
ذاكرة البيانات المؤقتة في Vercel
إذا تم نشر تطبيق Next.js الخاص بك على Vercel، نوصي بقراءة وثائق ذاكرة البيانات المؤقتة في Vercel لفهم أفضل للميزات الخاصة بـ Vercel.
ذاكرة المسار الكامل المؤقتة
مصطلحات ذات صلة:
قد ترى مصطلحات التحسين الثابت التلقائي أو توليد الموقع الثابت أو التصيير الثابت تُستخدم بالتبادل للإشارة إلى عملية تصيير وتخزين مسارات تطبيقك مؤقتًا في وقت البناء.
يُصَيِّر Next.js المسارات ويخزنها مؤقتًا تلقائيًا في وقت البناء. هذا تحسين يسمح لك بتقديم المسار المخزن مؤقتًا بدلاً من التصيير على الخادم لكل طلب، مما يؤدي إلى تحميل أسرع للصفحات.
لفهم كيفية عمل ذاكرة المسار الكامل المؤقتة، من المفيد النظر إلى كيفية تعامل React مع التصيير، وكيف يخزن Next.js النتيجة:
1. تصيير React على الخادم
على الخادم، يستخدم Next.js واجهات برمجة تطبيقات React لتنظيم التصيير. يتم تقسيم عمل التصيير إلى أجزاء: حسب أجزاء المسار الفردية وحدود Suspense.
يتم تصيير كل جزء في خطوتين:
- يُصَيِّر React مكونات الخادم إلى تنسيق بيانات خاص مُحَسَّن للبث، يُسمى حمولة مكون خادم React.
- يستخدم Next.js حمولة مكون خادم React وتعليمات JavaScript لمكون العميل لتصيير HTML على الخادم.
هذا يعني أنه لا يتعين علينا الانتظار حتى يتم تصيير كل شيء قبل تخزين العمل مؤقتًا أو إرسال استجابة. بدلاً من ذلك، يمكننا بث استجابة أثناء اكتمال العمل.
ما هي حمولة مكون خادم React؟
حمولة مكون خادم React هي تمثيل ثنائي مضغوط لشجرة مكونات خادم React المُصَيَّرة. يتم استخدامها بواسطة React على العميل لتحديث DOM للمتصفح. تحتوي حمولة مكون خادم React على:
- نتيجة تصيير مكونات الخادم
- عناصر نائبة لمكان تصيير مكونات العميل ومراجع لملفات JavaScript الخاصة بها
- أي خصائص تم تمريرها من مكون خادم إلى مكون عميل
لمعرفة المزيد، راجع وثائق مكونات الخادم.
2. تخزين Next.js مؤقتًا على الخادم (ذاكرة المسار الكامل المؤقتة)

السلوك الافتراضي لـ Next.js هو تخزين نتيجة التصيير (حمولة مكون خادم React وHTML) لمسار على الخادم مؤقتًا. ينطبق هذا على المسارات المصَيَّرة بشكل ثابت في وقت البناء، أو أثناء إعادة التحقق.
3. ترطيب React والمصالحة على العميل
في وقت الطلب، على العميل:
- يتم استخدام HTML لعرض معاينة أولية سريعة غير تفاعلية لمكونات العميل والخادم.
- تُستخدم حمولة مكونات خادم React لمصالحة أشجار مكونات العميل والخادم المُصَيَّرة، وتحديث DOM.
- تُستخدم تعليمات JavaScript لترطيب مكونات العميل وجعل التطبيق تفاعليًا.
4. تخزين Next.js مؤقتًا على العميل (ذاكرة الموجه المؤقتة)
يتم تخزين حمولة مكون خادم React في ذاكرة الموجه المؤقتة على جانب العميل - وهي ذاكرة تخزين مؤقت في الذاكرة، مقسمة حسب أجزاء المسار الفردية. تُستخدم ذاكرة الموجه المؤقتة لتحسين تجربة التنقل عن طريق تخزين المسارات التي تمت زيارتها مسبقًا وجلب المسارات المستقبلية مسبقًا.
5. التنقلات اللاحقة
في التنقلات اللاحقة أو أثناء الجلب المسبق (prefetching)، سيتحقق Next.js مما إذا كان حمولة مكونات الخادم (React Server Components Payload) مخزنة في ذاكرة التوجيه (Router Cache). إذا كانت موجودة، فسيتم تخطي إرسال طلب جديد إلى الخادم.
إذا لم تكن أجزاء المسار موجودة في الذاكرة المؤقتة، سيقوم Next.js بجلب حمولة مكونات الخادم من الخادم، وملء ذاكرة التوجيه على العميل.
العرض الثابت والديناميكي
ما إذا كان المسار مخزناً مؤقتاً أثناء البناء أم لا يعتمد على ما إذا كان يتم عرضه بشكل ثابت أو ديناميكي. يتم تخزين المسارات الثابتة مؤقتاً افتراضياً، بينما يتم عرض المسارات الديناميكية وقت الطلب ولا يتم تخزينها مؤقتاً.
يوضح هذا الرسم البياني الفرق بين المسارات المعروضة بشكل ثابت وديناميكي، مع البيانات المخزنة وغير المخزنة مؤقتاً:

تعرف على المزيد حول العرض الثابت والديناميكي.
المدة الزمنية
افتراضياً، تكون ذاكرة المسار الكاملة (Full Route Cache) دائمة. وهذا يعني أن ناتج العرض يتم تخزينه مؤقتاً عبر طلبات المستخدمين.
إبطال الصلاحية
هناك طريقتان يمكنك من خلالهما إبطال صلاحية ذاكرة المسار الكاملة:
- إعادة التحقق من البيانات: إعادة التحقق من ذاكرة البيانات (Data Cache) سيقوم بدوره بإبطال صلاحية ذاكرة التوجيه (Router Cache) عن طريق إعادة عرض المكونات على الخادم وتخزين ناتج العرض الجديد مؤقتاً.
- إعادة النشر: على عكس ذاكرة البيانات التي تظل عبر عمليات النشر، يتم مسح ذاكرة المسار الكاملة عند عمليات النشر الجديدة.
الانسحاب
يمكنك الانسحاب من ذاكرة المسار الكاملة، أو بعبارة أخرى، عرض المكونات ديناميكياً لكل طلب وارد، عن طريق:
- استخدام وظيفة ديناميكية (Dynamic Function): سيؤدي هذا إلى إخراج المسار من ذاكرة المسار الكاملة وعرضه ديناميكياً وقت الطلب. لا يزال يمكن استخدام ذاكرة البيانات.
- استخدام خيارات تكوين جزء المسار
dynamic = 'force-dynamic'
أوrevalidate = 0
: سيؤدي هذا إلى تخطي ذاكرة المسار الكاملة وذاكرة البيانات. مما يعني أنه سيتم عرض المكونات وجلب البيانات في كل طلب وارد إلى الخادم. ستظل ذاكرة التوجيه سارية لأنها ذاكرة على جانب العميل. - الانسحاب من ذاكرة البيانات (Data Cache): إذا كان للمسار طلب
fetch
غير مخزن مؤقتاً، فسيؤدي هذا إلى إخراج المسار من ذاكرة المسار الكاملة. سيتم جلب البيانات لطلبfetch
المحدد لكل طلب وارد. ستظل طلباتfetch
الأخرى التي لا تنسحب من التخزين المؤقت مخزنة في ذاكرة البيانات. وهذا يسمح بمزيج من البيانات المخزنة وغير المخزنة مؤقتاً.
ذاكرة التوجيه (Router Cache)
المصطلحات ذات الصلة:
قد تشاهد الإشارة إلى ذاكرة التوجيه باسم ذاكرة جانب العميل (Client-side Cache) أو ذاكرة الجلب المسبق (Prefetch Cache). بينما تشير ذاكرة الجلب المسبق إلى أجزاء المسار التي تم جلبها مسبقاً، تشير ذاكرة جانب العميل إلى ذاكرة التوجيه بأكملها، والتي تشمل كلاً من الأجزاء التي تمت زيارتها والتي تم جلبها مسبقاً. هذه الذاكرة المؤقتة تنطبق تحديداً على Next.js ومكونات الخادم، وهي مختلفة عن bfcache المتصفح، على الرغم من أن لها نتيجة مماثلة.
يمتلك Next.js ذاكرة مؤقتة على جانب العميل في الذاكرة تقوم بتخزين حمولة مكونات الخادم (React Server Component Payload)، مقسمة حسب أجزاء المسار الفردية، طوال مدة جلسة المستخدم. وهذا ما يسمى بذاكرة التوجيه (Router Cache).
كيف تعمل ذاكرة التوجيه

عندما يتنقل المستخدمون بين المسارات، يقوم Next.js بتخزين أجزاء المسار التي تمت زيارتها ويجلب مسبقاً المسارات التي من المحتمل أن يتنقل إليها المستخدم (بناءً على مكونات <Link>
في نطاق الرؤية لديهم).
ينتج عن هذا تحسين تجربة التنقل للمستخدم:
- تنقل فوري للخلف/الأمام لأن المسارات التي تمت زيارتها مخزنة مؤقتاً وتنقل سريع إلى المسارات الجديدة بسبب الجلب المسبق والعرض الجزئي (Partial Rendering).
- لا يوجد إعادة تحميل كاملة للصفحة بين التنقلات ويتم الحفاظ على حالة React وحالة المتصفح.
الفرق بين ذاكرة التوجيه وذاكرة المسار الكاملة:
تقوم ذاكرة التوجيه بتخزين حمولة مكونات الخادم (React Server Component Payload) مؤقتاً في المتصفح طوال مدة جلسة المستخدم، بينما تقوم ذاكرة المسار الكاملة بتخزين حمولة مكونات الخادم وHTML بشكل دائم على الخادم عبر طلبات متعددة للمستخدمين.
بينما تقوم ذاكرة المسار الكاملة بتخزين المسارات المعروضة بشكل ثابت فقط، تنطبق ذاكرة التوجيه على كل من المسارات المعروضة بشكل ثابت وديناميكي.
المدة الزمنية
يتم تخزين الذاكرة المؤقتة في الذاكرة المؤقتة للمتصفح. هناك عاملان يحددان المدة التي تستمر فيها ذاكرة التوجيه:
- الجلسة: تظل الذاكرة المؤقتة عبر التنقل. ومع ذلك، يتم مسحها عند تحديث الصفحة.
- فترة الإبطال التلقائي: يتم إبطال صلاحية ذاكرة جزء فردي تلقائياً بعد وقت محدد. تعتمد المدة على ما إذا كان المسار معروضاً بشكل ثابت أو ديناميكي:
- المعروض ديناميكياً: 30 ثانية
- المعروض ثابتاً: 5 دقائق
بينما يؤدي تحديث الصفحة إلى مسح جميع الأجزاء المخزنة مؤقتاً، تؤثر فترة الإبطال التلقائي فقط على الجزء الفردي من وقت آخر وصول إليه أو إنشائه.
عن طريق إضافة prefetch={true}
أو استدعاء router.prefetch
لمسار معروض ديناميكياً، يمكنك اختيار التخزين المؤقت لمدة 5 دقائق.
إبطال الصلاحية
هناك طريقتان يمكنك من خلالهما إبطال صلاحية ذاكرة التوجيه:
- في إجراء خادم (Server Action):
- إعادة التحقق من البيانات حسب الطلب عن طريق المسار باستخدام (
revalidatePath
) أو عن طريق علامة الذاكرة المؤقتة باستخدام (revalidateTag
) - يؤدي استخدام
cookies.set
أوcookies.delete
إلى إبطال صلاحية ذاكرة التوجيه لمنع المسارات التي تستخدم ملفات تعريف الارتباط من أن تصبح قديمة (مثل المصادقة).
- إعادة التحقق من البيانات حسب الطلب عن طريق المسار باستخدام (
- يؤدي استدعاء
router.refresh
إلى إبطال صلاحية ذاكرة التوجيه وإجراء طلب جديد إلى الخادم للمسار الحالي.
الانسحاب
لا يمكن الانسحاب من ذاكرة التوجيه.
يمكنك الانسحاب من الجلب المسبق عن طريق تعيين خاصية prefetch
لمكون <Link>
على false
. ومع ذلك، سيظل هذا يقوم بتخزين أجزاء المسار مؤقتاً لمدة 30 ثانية للسماح بالتنقل الفوري بين الأجزاء المتداخلة، مثل أشرطة التبويب، أو التنقل للخلف والأمام. ستظل المسارات التي تمت زيارتها مخزنة مؤقتاً.
تفاعلات الذاكرة المؤقتة
عند تكوين آليات التخزين المؤقت المختلفة، من المهم فهم كيفية تفاعلها مع بعضها البعض:
ذاكرة البيانات وذاكرة المسار الكاملة
- إعادة التحقق من البيانات أو الانسحاب من ذاكرة البيانات سوف يبطل صلاحية ذاكرة المسار الكاملة، لأن ناتج العرض يعتمد على البيانات.
- إبطال صلاحية ذاكرة المسار الكاملة أو الانسحاب منها لا يؤثر على ذاكرة البيانات. يمكنك عرض مسار ديناميكي يحتوي على كل من البيانات المخزنة وغير المخزنة مؤقتاً. هذا مفيد عندما تستخدم معظم صفحتك بيانات مخزنة مؤقتاً، ولكن لديك بعض المكونات التي تعتمد على البيانات التي يجب جلبها وقت الطلب. يمكنك العرض الديناميكي دون القلق بشأن تأثير الأداء لإعادة جلب جميع البيانات.
ذاكرة البيانات وذاكرة التوجيه على جانب العميل
- إعادة التحقق من ذاكرة البيانات في معالج المسار (Route Handler) لن يبطل صلاحية ذاكرة التوجيه على الفور لأن معالج المسار غير مرتبط بمسار محدد. هذا يعني أن ذاكرة التوجيه ستستمر في تقديم الحمولة السابقة حتى تحديث قوي، أو انتهاء فترة الإبطال التلقائي.
- لإبطال صلاحية ذاكرة البيانات وذاكرة التوجيه على الفور، يمكنك استخدام
revalidatePath
أوrevalidateTag
في إجراء خادم (Server Action).
واجهات برمجة التطبيقات (APIs)
يوضح الجدول التالي نظرة عامة على كيفية تأثير واجهات برمجة التطبيقات المختلفة لـ Next.js على التخزين المؤقت:
الواجهة البرمجية | ذاكرة التوجيه | ذاكرة المسار الكاملة | ذاكرة البيانات | ذاكرة React |
---|---|---|---|---|
<Link prefetch> | تخزين مؤقت | |||
router.prefetch | تخزين مؤقت | |||
router.refresh | إعادة التحقق | |||
fetch | تخزين مؤقت | تخزين مؤقت | ||
fetch options.cache | تخزين مؤقت أو انسحاب | |||
fetch options.next.revalidate | إعادة التحقق | إعادة التحقق | ||
fetch options.next.tags | تخزين مؤقت | تخزين مؤقت | ||
revalidateTag | إعادة التحقق (إجراء خادم) | إعادة التحقق | إعادة التحقق | |
revalidatePath | إعادة التحقق (إجراء خادم) | إعادة التحقق | إعادة التحقق | |
const revalidate | إعادة التحقق أو انسحاب | إعادة التحقق أو انسحاب | ||
const dynamic | تخزين مؤقت أو انسحاب | تخزين مؤقت أو انسحاب | ||
cookies | إعادة التحقق (إجراء خادم) | انسحاب | ||
headers , useSearchParams , searchParams | انسحاب | |||
generateStaticParams | تخزين مؤقت | |||
React.cache | تخزين مؤقت | |||
unstable_cache (قريباً) |
<Link>
افتراضياً، يقوم مكون <Link>
تلقائياً بجلب المسارات مسبقاً من ذاكرة المسار الكاملة وإضافة حمولة مكونات الخادم (React Server Component Payload) إلى ذاكرة التوجيه.
لتعطيل الجلب المسبق، يمكنك تعيين خاصية prefetch
على false
. ولكن هذا لن يتخطى التخزين المؤقت بشكل دائم، سيظل جزء المسار مخزناً مؤقتاً على جانب العميل عندما يزور المستخدم المسار.
تعرف على المزيد حول مكون <Link>
.
router.prefetch
يمكن استخدام خيار prefetch
في خطاف useRouter
لجلب مسار مسبقاً يدوياً. هذا يضيف حمولة مكونات الخادم (React Server Component Payload) إلى ذاكرة التوجيه.
راجع مرجع واجهة برمجة التطبيقات لـخطاف useRouter
.
router.refresh
يمكن استخدام خيار refresh
في خطاف useRouter
لتحديث مسار يدوياً. هذا يمسح ذاكرة التوجيه بالكامل، ويجعل طلباً جديداً إلى الخادم للمسار الحالي. لا يؤثر refresh
على ذاكرة البيانات أو ذاكرة المسار الكاملة.
سيتم التوفيق بين نتيجة العرض على العميل مع الحفاظ على حالة React وحالة المتصفح.
راجع مرجع واجهة برمجة التطبيقات لـخطاف useRouter
.
fetch
يتم تخزين البيانات التي يتم إرجاعها من fetch
تلقائياً في ذاكرة البيانات.
// مخزن مؤقت افتراضياً. `force-cache` هو الخيار الافتراضي ويمكن حذفه.
fetch(`https://...`, { cache: 'force-cache' })
راجع مرجع واجهة برمجة التطبيقات لـ fetch
لمزيد من الخيارات.
fetch options.cache
يمكنك الانسحاب من تخزين بيانات طلبات fetch
الفردية عن طريق تعيين خيار cache
على no-store
:
// الانسحاب من التخزين المؤقت
fetch(`https://...`, { cache: 'no-store' })
نظراً لأن ناتج العرض يعتمد على البيانات، فإن استخدام cache: 'no-store'
سيتخطى أيضاً ذاكرة المسار الكاملة للمسار حيث يتم استخدام طلب fetch
. أي أن المسار سيتم عرضه ديناميكياً في كل طلب، ولكن يمكنك الحصول على طلبات بيانات أخرى مخزنة مؤقتاً في نفس المسار.
راجع مرجع واجهة برمجة التطبيقات لـ fetch
لمزيد من الخيارات.
fetch options.next.revalidate
يمكنك استخدام خيار next.revalidate
لـ fetch
لتعيين فترة إعادة التحقق (بالثواني) لطلب fetch
فردي. سيؤدي هذا إلى إعادة التحقق من ذاكرة البيانات، والتي بدورها ستقوم بإعادة التحقق من ذاكرة المسار الكاملة. سيتم جلب بيانات جديدة، وسيتم إعادة عرض المكونات على الخادم.
// إعادة التحقق على الأكثر بعد ساعة واحدة
fetch(`https://...`, { next: { revalidate: 3600 } })
راجع مرجع واجهة برمجة التطبيقات لـ fetch
لمزيد من الخيارات.
fetch options.next.tags
و revalidateTag
يمتلك Next.js نظام وضع علامات على الذاكرة المؤقتة للتخزين المؤقت الدقيق للبيانات وإعادة التحقق منها.
- عند استخدام
fetch
أوunstable_cache
، لديك خيار وضع علامات على إدخالات الذاكرة المؤقتة بواحدة أو أكثر من العلامات. - ثم يمكنك استدعاء
revalidateTag
لمسح إدخالات الذاكرة المؤقتة المرتبطة بهذه العلامة.
على سبيل المثال، يمكنك تعيين علامة عند جلب البيانات:
// تخزين البيانات مع علامة
fetch(`https://...`, { next: { tags: ['a', 'b', 'c'] } })
ثم استدعاء revalidateTag
مع علامة لمسح إدخال الذاكرة المؤقتة:
// إعادة التحقق من الإدخالات بعلامة محددة
revalidateTag('a')
هناك مكانان يمكنك استخدام revalidateTag
فيهما، اعتماداً على ما تحاول تحقيقه:
- معالجات المسار (Route Handlers) - لإعادة التحقق من البيانات استجابةً لحدث طرف ثالث (مثل webhook). هذا لن يبطل صلاحية ذاكرة التوجيه على الفور لأن معالج المسار غير مرتبط بمسار محدد.
- إجراءات الخادم (Server Actions) - لإعادة التحقق من البيانات بعد إجراء المستخدم (مثل تقديم نموذج). هذا سيبطل صلاحية ذاكرة التوجيه للمسار المرتبط.
revalidatePath
تتيح لك revalidatePath
إعادة التحقق يدويًا من البيانات و إعادة عرض مقاطع المسار أسفل مسار معين في عملية واحدة. يؤدي استدعاء طرق revalidatePath
إلى إعادة التحقق من ذاكرة التخزين المؤقت للبيانات (Data Cache)، مما يؤدي بدوره إلى إبطال ذاكرة التخزين المؤقت الكاملة للمسار (Full Route Cache).
revalidatePath('/')
هناك مكانان يمكنك استخدام revalidatePath
فيهما، اعتمادًا على ما تحاول تحقيقه:
- معالجات المسار (Route Handlers) - لإعادة التحقق من البيانات استجابةً لحدث طرف ثالث (مثل webhook).
- إجراءات الخادم (Server Actions) - لإعادة التحقق من البيانات بعد تفاعل المستخدم (مثل تقديم نموذج، النقر على زر).
راجع مرجع واجهة برمجة التطبيقات لـ revalidatePath
لمزيد من المعلومات.
revalidatePath
مقابلrouter.refresh
:يؤدي استدعاء
router.refresh
إلى مسح ذاكرة التخزين المؤقت للموجه (Router cache)، وإعادة عرض مقاطع المسار على الخادم دون إبطال ذاكرة التخزين المؤقت للبيانات (Data Cache) أو ذاكرة التخزين المؤقت الكاملة للمسار (Full Route Cache).الفرق هو أن
revalidatePath
تفرغ ذاكرة التخزين المؤقت للبيانات وذاكرة التخزين المؤقت الكاملة للمسار، بينماrouter.refresh()
لا تغير ذاكرة التخزين المؤقت للبيانات وذاكرة التخزين المؤقت الكاملة للمسار، لأنها واجهة برمجة تطبيقات من جانب العميل.
الدوال الديناميكية (Dynamic Functions)
cookies
، headers
، useSearchParams
، و searchParams
هي دوال ديناميكية تعتمد على معلومات الطلب الواردة أثناء التشغيل. استخدامها سيؤدي إلى استبعاد المسار من ذاكرة التخزين المؤقت الكاملة للمسار (Full Route Cache)، بمعنى آخر، سيتم عرض المسار ديناميكيًا.
cookies
استخدام cookies.set
أو cookies.delete
في إجراء خادم (Server Action) يبطل ذاكرة التخزين المؤقت للموجه (Router Cache) لمنع المسارات التي تستخدم ملفات تعريف الارتباط (cookies) من أن تصبح قديمة (على سبيل المثال، لتعكس تغييرات المصادقة).
راجع مرجع واجهة برمجة التطبيقات لـ cookies
.
خيارات تكوين المقطع (Segment Config Options)
يمكن استخدام خيارات تكوين مقطع المسار (Route Segment Config) لتجاوز الإعدادات الافتراضية لمقطع المسار أو عندما لا تتمكن من استخدام واجهة برمجة التطبيقات fetch
(على سبيل المثال، عميل قاعدة بيانات أو مكتبات طرف ثالث).
ستؤدي خيارات تكوين مقطع المسار التالية إلى استبعاد ذاكرة التخزين المؤقت للبيانات (Data Cache) وذاكرة التخزين المؤقت الكاملة للمسار (Full Route Cache):
const dynamic = 'force-dynamic'
const revalidate = 0
راجع توثيق تكوين مقطع المسار (Route Segment Config) لمزيد من الخيارات.
generateStaticParams
بالنسبة للمقاطع الديناميكية (dynamic segments) (على سبيل المثال app/blog/[slug]/page.js
)، يتم تخزين المسارات المقدمة من generateStaticParams
في ذاكرة التخزين المؤقت الكاملة للمسار (Full Route Cache) أثناء وقت البناء. في وقت الطلب، سيخزن Next.js أيضًا المسارات التي لم تكن معروفة في وقت البناء عند زيارتها لأول مرة.
يمكنك تعطيل التخزين المؤقت في وقت الطلب باستخدام خيار export const dynamicParams = false
في مقطع المسار. عند استخدام خيار التكوين هذا، سيتم تقديم المسارات المقدمة من generateStaticParams
فقط، وستؤدي المسارات الأخرى إلى خطأ 404 أو تطابق (في حالة المسارات الشاملة (catch-all routes)).
راجع مرجع واجهة برمجة التطبيقات لـ generateStaticParams
.
دالة React cache
تتيح لك دالة React cache
تخزين القيمة المرجعة للدالة مؤقتًا، مما يسمح لك باستدعاء نفس الدالة عدة مرات مع تنفيذها مرة واحدة فقط.
نظرًا لأن طلبات fetch
يتم تخزينها مؤقتًا تلقائيًا، فلا تحتاج إلى تغليفها في React cache
. ومع ذلك، يمكنك استخدام cache
لتخزين طلبات البيانات يدويًا للحالات التي لا تكون فيها واجهة برمجة التطبيقات fetch
مناسبة. على سبيل المثال، بعض عملاء قواعد البيانات، أو عملاء نظام إدارة المحتوى (CMS)، أو عملاء GraphQL.
import { cache } from 'react'
import db from '@/lib/db'
export const getItem = cache(async (id: string) => {
const item = await db.item.findUnique({ id })
return item
})
import { cache } from 'react'
import db from '@/lib/db'
export const getItem = cache(async (id) => {
const item = await db.item.findUnique({ id })
return item
})
unstable_cache
unstable_cache
هي واجهة برمجة تطبيقات تجريبية لإضافة قيم إلى ذاكرة التخزين المؤقت للبيانات (Data Cache) عندما لا تكون واجهة برمجة التطبيقات fetch
مناسبة. على سبيل المثال، عند استخدام عملاء قواعد البيانات، أو عملاء نظام إدارة المحتوى (CMS)، أو GraphQL.
import { unstable_cache } from 'next/cache'
export default async function Page() {
const cachedData = await unstable_cache(
async () => {
const data = await db.query('...')
return data
},
['cache-key'],
{
tags: ['a', 'b', 'c'],
revalidate: 10,
}
)()
}
تحذير: هذه الواجهة قيد التطوير، ولا نوصي باستخدامها في الإنتاج. تم سردها هنا لإظهار الاتجاه المستقبلي لـ ذاكرة التخزين المؤقت للبيانات (Data Cache).