Next.js 16 cacheComponents: ترحيل 91,000 صفحة بدون توقف
ينطلق نشرك الخاص بك في الساعة 2:14 صباحاً. واحد وتسعون ألف صفحة منتج—أشجار الفئات، والمتغيرات المترجمة عبر 14 سوقاً، والمحتوى الافتتاحي للـ SEO—تنتقل من App Router الخاص بـ Next.js 14 إلى API cacheComponents في v16. تراقب أول طلب يتدفق في سجلات Vercel. TTFB ترتفع إلى 1.8 ثانية. تأتيك رسائل Slack. لمدة ثمانية عشر شهراً كنت تحارب نموذج الذاكرة الافتراضي القديم: الأسعار القديمة، استدعاءات revalidateTag التي تطلق متأخرة جداً، تذاكر دعم العملاء التي تلوم "الموقع الإلكتروني". قلب Next.js 15 التخزين المؤقت؛ أعطاك v16 cacheComponents لإعادة الاشتراك جراحياً. اخترت الترحيل على الموت البطيء بألف خلل في الذاكرة. الآن تحدق في حركة مرور حقيقية، وأخطاء حقيقية، وحادثة إنتاج قبل ساعتين من الفجر. إليك ما انكسر، وما صمد، والفروق في الأداء التي لم تتنبأ بها أي مجموعة معايير.
جدول المحتويات
- مشكلة التخزين المؤقت التي كان لدينا فعلاً
- ما تغير في Next.js 15 و 16
- فهم cacheComponents
- استراتيجية الترحيل لدينا ل 91,000 صفحة
- التنفيذ: خطوة بخطوة
- نتائج الأداء والمعايير
- المزالق والمشاكل
- متى يجب عليك استخدام cacheComponents ومتى لا
- الأسئلة الشائعة

مشكلة التخزين المؤقت التي كان لدينا فعلاً
دعني أصور لك الصورة. في App Router الخاص بـ Next.js 14، كانت طلبات fetch في Server Components مخزنة مؤقتاً بشكل افتراضي. استمر Data Cache عبر النشرات. خزنت Full Route Cache HTML المعروض وحمولات RSC وقت البناء. وأبقى Router Cache على العميل الجانب حول البقايا المجلوبة لـ... حسناً، أطول مما تتوقع.
بالنسبة لموقع يضم 91,000 صفحة، خلق نهج افتراضي-التخزين-المؤقت-كل شيء فئتين من المشاكل:
البيانات القديمة في كل مكان. تحديث أسعار المنتجات في نظام إدارة المحتوى بدون رأس (Sanity، في حالتنا) لكن نتائج الجلب المخزنة مؤقتاً لزجت حولها. كان لدينا استدعاءات revalidateTag مبعثرة عبر 47 خادم عمل مختلف. هل أخطأت في وضع علامة واحدة؟ يرى العميل سعر أمس. كان لدينا بالفعل قناة Slack تسمى #cache-crimes حيث أبلغ فريق المحتوى عن الصفحات القديمة.
أوقات بناء من الجحيم. استغرقت الإنشاء الثابت الكامل لـ 91,000 صفحة أكثر من 3 ساعات. انتقلنا إلى ISR مع revalidate: 3600 لمعظم الصفحات، لكن التفاعل بين ISR وData Cache وإعادة التحقق من الطلب كان صعباً حقاً على التفكير فيه. كان يقضي المطورون الجدد في الفريق أسبوعيهم الأول فقط يفهمون طبقات التخزين المؤقت.
ضريبة النموذج العقلي
إليك ما أعتقد أن الناس يقللون من شأنه: التكلفة المعرفية للتخزين المؤقت الضمني. عندما يكون التخزين المؤقت هو الافتراضي وتختار عدم الاشتراك، يتطلب كل مكون جديد منك السؤال "هل يجب أن يكون هذا مخزناً مؤقتاً؟" ثم تذكر إضافة التوجيه الصحيح إذا كانت الإجابة بـ لا. عندما لا يكون التخزين المؤقت هو الافتراضي وتختار الاشتراك، تفكر فقط في التخزين المؤقت عندما تريده بنشاط. هذا نموذج بشكل أساسي مختلف -- وأفضل --.
ما تغير في Next.js 15 و 16
كان Next.js 15 التحول الفلسفي الكبير. قلب الفريق الافتراضيات:
| السلوك | Next.js 14 | Next.js 15 | Next.js 16 |
|---|---|---|---|
fetch() في Server Components |
مخزن مؤقتاً بشكل افتراضي | غير مخزن مؤقتاً بشكل افتراضي | غير مخزن مؤقتاً بشكل افتراضي |
| Route Handlers (GET) | مخزن مؤقتاً بشكل افتراضي | غير مخزن مؤقتاً بشكل افتراضي | غير مخزن مؤقتاً بشكل افتراضي |
| Client Router Cache | 30 ثانية (ديناميكي) / 5 دقائق (ثابت) | 0 ثانية لقطاعات الصفحة | 0 افتراضي ثانية، قابل للتكوين |
| Full Route Cache | مفعّل للمسارات الثابتة | نفس الشيء | نفس الشيء، مع تحسينات cacheLife |
| التخزين المؤقت على مستوى المكون | unstable_cache |
use cache directive (تجريبي) |
cacheComponents API (مستقر) |
أدخل Next.js 15 توجيه use cache كميزة تجريبية خلف علم. Next.js 16، الذي تم إصداره في أوائل 2025، استقر هذا كخيار تكوين cacheComponents وتوجيه "use cache" المرتبط، جنباً إلى جنب مع cacheLife لتحديد ملفات تعريف ذاكرة التخزين المؤقت المخصصة و cacheTag للإبطال الموجه.
الرؤية الأساسية: تحرك التخزين المؤقت من كونه سلوكاً إطار عمل ضمنياً إلى خيار مطور صريح على مستوى المكون. هذا أمر كبير حقاً للمواقع الكبيرة.
فهم cacheComponents
ميزة cacheComponents في next.config.js تمكّن التخزين المؤقت على مستوى المكون من خلال توجيه "use cache". إليك الإعداد الأساسي:
// next.config.js (Next.js 16)
const nextConfig = {
experimental: {
cacheComponents: true,
},
};
module.exports = nextConfig;
بمجرد التمكين، يمكنك إضافة "use cache" في أعلى أي Server Component غير متزامن أو server action أو حتى ملف layout:
// app/products/[slug]/page.tsx
"use cache";
import { cacheLife, cacheTag } from 'next/cache';
export default async function ProductPage({ params }: { params: { slug: string } }) {
cacheLife('products'); // custom cache profile
cacheTag(`product-${params.slug}`);
const product = await fetchProduct(params.slug);
return (
<div>
<h1>{product.name}</h1>
<ProductDetails product={product} />
<DynamicPricing productId={product.id} /> {/* This component is NOT cached */}
</div>
);
}
ملفات تعريف cacheLife
هنا حيث يصبح الأمر مثيراً للاهتمام بالنسبة للمواقع الكبيرة. تحدد ملفات تعريف ذاكرة التخزين المؤقت المسماة في next.config.js:
const nextConfig = {
experimental: {
cacheComponents: true,
cacheLife: {
products: {
stale: 300, // serve stale for 5 minutes
revalidate: 3600, // revalidate after 1 hour
expire: 86400, // hard expire after 24 hours
},
editorial: {
stale: 3600,
revalidate: 86400,
expire: 604800, // 7 days
},
navigation: {
stale: 86400,
revalidate: 604800,
expire: 2592000, // 30 days
},
},
},
};
النموذج ثلاثي المستويات (stale, revalidate, expire) يخطط بشكل جميل لدلالات stale-while-revalidate. خلال نافذة stale، يتم تقديم المحتوى المخزن مؤقتاً على الفور. بعد stale لكن قبل expire، يبدأ إعادة التحقق في الخلفية. بعد expire، دخل ذاكرة التخزين المؤقت لم يعد موجوداً.
cacheTag للإبطال
تحل دالة cacheTag محل نمط revalidateTag القديم بشيء أكثر قابلية للتكوين:
import { revalidateTag } from 'next/cache';
// In a webhook handler or server action:
export async function handleProductUpdate(productSlug: string) {
revalidateTag(`product-${productSlug}`);
revalidateTag('product-listing'); // invalidate listing pages too
}
لم يتغير هذا الجزء كثيراً من Next.js 15، لكنه يعمل بشكل أفضل بكثير مع cacheComponents لأنك تضع علامات على مكونات مخزنة مؤقتاً صريحة بدلاً من محاولة إبطال ذاكرة تخزين مؤقت غير واضحة على مستوى الإطار.

استراتيجية الترحيل لدينا ل 91,000 صفحة
لم نقم بهذا في لقطة واحدة. مع 91,000 صفحة عبر 14 لغة، كان الترحيل الكبير سيكون متهوراً. إليك كيف قسمنا الأمور:
المرحلة 1: الترقية إلى Next.js 16، بدون تغييرات ذاكرة التخزين المؤقت (الأسبوع 1-2)
قمنا بترقية من Next.js 14.2 إلى 16.0 دون تمكين cacheComponents. وحده هذا غيّر السلوك لأن طلبات fetch لم تعد مخزنة مؤقتاً بشكل افتراضي. توقعنا انحدارات TTFB وحصلنا عليها:
- ارتفع متوسط TTFB من 180ms إلى 340ms على صفحات المنتج
- زيادة حمل خادم الأصل بحوالي 60% (عقد CDN Sanity الخاص بنا عقد بشكل جيد، لكن نقاط النهاية API المخصصة لدينا لم تفعل ذلك)
- أصبح إعادة تحقق ISR أسرع فعلياً لأنه كان هناك حالة ذاكرة تخزين مؤقت أقل لإدارتها
أكد هذا على ما اشتبهنا فيه: كنا نعتمد بشدة على التخزين المؤقت الضمني، وكثير من صفحاتنا كانت تحتاج فعلاً إلى التخزين المؤقت -- فقط التخزين المؤقت الصريح والمقصود.
المرحلة 2: التدقيق وتصنيف الصفحات (الأسبوع 3)
صنفنا كل مسار في تطبيقنا:
| نوع الصفحة | العدد | استراتيجية ذاكرة التخزين المؤقت | ملف تعريف cacheLife |
|---|---|---|---|
| صفحات تفاصيل المنتج | 42,000 | التخزين المؤقت مع علامة المنتج | products (5min stale / 1hr revalidate) |
| صفحات قائمة الفئات | 3,200 | التخزين المؤقت مع علامة الفئة | products (5min stale / 1hr revalidate) |
| صفحات افتتاحية/مدونة | 8,400 | التخزين المؤقت بقوة | editorial (1hr stale / 24hr revalidate) |
| المتغيرات المترجمة | 31,647 | نفس الصفحة الأساسية | موروثة من القاعدة |
| صفحات ديناميكية/حساب | 6,000 | لا ذاكرة تخزين مؤقت | N/A |
المرحلة 3: تمكين cacheComponents، إضافة التوجيهات (الأسبوع 4-6)
قمنا بتمكين العلم وبدأنا بإضافة توجيهات "use cache". القرار الرئيسي: قمنا بالتخزين المؤقت على مستوى الصفحة لمعظم المسارات، لكن على مستوى المكون للصفحات التي تحتوي على محتوى ثابت/ديناميكي مختلط.
بالنسبة لصفحات المنتج، كانت معلومات المنتج والصور مخزنة مؤقتاً، لكن مكون التسعير وحالة المخزون تم تركها بدون تخزين مؤقت:
// components/ProductInfo.tsx
"use cache";
import { cacheLife, cacheTag } from 'next/cache';
export async function ProductInfo({ slug }: { slug: string }) {
cacheLife('products');
cacheTag(`product-${slug}`, 'product-info');
const product = await getProduct(slug);
return (
<section>
<h1>{product.name}</h1>
<p>{product.description}</p>
<ProductImages images={product.images} />
</section>
);
}
// components/DynamicPricing.tsx
// NO "use cache" directive -- always fresh
export async function DynamicPricing({ productId }: { productId: string }) {
const pricing = await getPricing(productId); // hits pricing API every request
return (
<div className="pricing">
<span className="price">${pricing.current}</span>
{pricing.onSale && <span className="was-price">${pricing.original}</span>}
</div>
);
}
المرحلة 4: دمج Webhook (الأسبوع 7)
أعدنا توصيل صور Sanity الخاصة بنا للاتصال revalidateTag مع العلامات الصحيحة. كان هذا أبسط فعلاً من إعدادنا القديم لأن العلامات كانت الآن صريحة في الكود، وليس مبعثرة عبر خيارات الجلب.
// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache';
import { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
const body = await request.json();
const secret = request.headers.get('x-webhook-secret');
if (secret !== process.env.REVALIDATION_SECRET) {
return new Response('Unauthorized', { status: 401 });
}
switch (body._type) {
case 'product':
revalidateTag(`product-${body.slug.current}`);
revalidateTag('product-listing');
break;
case 'category':
revalidateTag(`category-${body.slug.current}`);
revalidateTag('navigation');
break;
case 'article':
revalidateTag(`article-${body.slug.current}`);
break;
}
return new Response('OK', { status: 200 });
}
التنفيذ: خطوة بخطوة
إذا كنت تقوم بترحيل مشابه، إليك كتيب العملية الذي سنوصي به (والذي نستخدمه الآن لـ مشاريع تطوير Next.js في Social Animal):
الخطوة 1: تمكين العلم
// next.config.js
module.exports = {
experimental: {
cacheComponents: true,
cacheLife: {
// Start with sensible defaults
default: {
stale: 60,
revalidate: 900,
expire: 86400,
},
},
},
};
الخطوة 2: ابحث عن مساراتك الساخنة
استخدم التحليلات الخاصة بك لتحديد الصفحات التي تحصل على أكثر حركة المرور وحيث يهم TTFB أكثر. بالنسبة لنا، كانت صفحات الفئات (حركة مرور عالية، محتوى مستقر نسبياً) وصفحات المنتج (حركة مرور عالية، محتوى متوسط الديناميكية).
الخطوة 3: أضف `"use cache"` من الأعلى للأسفل
ابدأ بـ layouts. إذا كان layout الجذر الخاص بك يجلب بيانات التنقل، قم بتخزين ذلك مؤقتاً أولاً -- إنها أعلى تأثير، أقل خطر تغيير:
// app/layout.tsx
// Note: "use cache" on layouts caches the layout shell
// Child pages still render independently
import { Navigation } from '@/components/Navigation';
export default async function RootLayout({ children }) {
return (
<html>
<body>
<Navigation /> {/* This component has its own "use cache" */}
{children}
</body>
</html>
);
}
الخطوة 4: ضع مراقبة
استخدمنا تحليل Vercel المدمج بالإضافة إلى تسجيل مخصص لتتبع معدلات cache hit. في الأسبوع الأول بعد تمكين cacheComponents، كان معدل cache hit لدينا 34٪ فقط. بعد ضبط مدد stale، ارتفع إلى 78٪.
نتائج الأداء والمعايير
إليك الأرقام الفعلية بعد الترحيل الكامل، المقاسة على مدى فترة 30 يوماً في خطة Vercel Pro:
| المقياس | قبل (Next.js 14) | بعد المرحلة 1 (v16، بدون ذاكرة تخزين مؤقت) | بعد الترحيل الكامل |
|---|---|---|---|
| متوسط TTFB (صفحات المنتج) | 180ms | 340ms | 95ms |
| متوسط TTFB (صفحات الفئة) | 220ms | 410ms | 72ms |
| متوسط TTFB (صفحات افتتاحية) | 150ms | 280ms | 45ms |
| P99 TTFB (جميع الصفحات) | 1,200ms | 2,100ms | 380ms |
| وقت البناء (الكامل) | 3h 12min | 2h 48min | 48min |
| استدعاءات دالة Vercel/يوم | 2.4M | 3.8M | 1.1M |
| فاتورة Vercel الشهرية | ~$840 | ~$1,200 | ~$520 |
| معدل cache hit | غير معروف (ضمني) | N/A | 78% |
| حوادث المحتوى القديم (#cache-crimes) | 8-12/week | 0 | 1-2/month |
يستحق تحسين وقت البناء الشرح. مع cacheComponents، انتقلنا بعيداً عن إنشاء جميع الـ 91,000 صفحة وقت البناء. بدلاً من ذلك، قمنا بإنشاء ثابت فقط من أفضل 5,000 صفحة (حسب حركة المرور) وتركنا الباقي ليتم إنشاؤه عند الطلب مع التخزين المؤقت. كان توجيه cacheComponents يعني أن هذه الصفحات عند الطلب حصلت على التخزين المؤقت بعد الزيارة الأولى، مع التحكم في عدم الحداثة cacheLife.
كان انخفاض فاتورة Vercel مهماً. عدد استدعاءات الدالة الأقل (بسبب التخزين المؤقت الصريح للمكونات) بالإضافة إلى أوقات البناء الأقصر يعني توفيرات تكلفة حقيقية. هذا الانخفاض ~$320/month يدفع ثمن نفسه.
المزالق والمشاكل
حدود التسلسل
يقوم توجيه "use cache" بإنشاء حد تسلسل. كل شيء يتم تمريره إلى مكون مخزن مؤقتاً كدعائم يجب أن يكون قابلاً للتسلسل. كان لدينا عدة مكونات تلقت وظائف callback أو عناصر React كدعائم -- تلك انكسرت على الفور. الإصلاح كان إعادة هيكلة لاستخدام أنماط التكوين بدلاً من ذلك:
// ❌ This breaks with "use cache"
"use cache";
export async function ProductCard({ product, onAddToCart }) {
// onAddToCart is a function -- not serializable!
}
// ✅ This works
"use cache";
export async function ProductCard({ product }) {
return (
<div>
<h2>{product.name}</h2>
{/* AddToCart is a Client Component, not cached */}
<AddToCartButton productId={product.id} />
</div>
);
}
معاملات ديناميكية واتفجار مساحة مفتاح ذاكرة التخزين المؤقت
مع 91,000 صفحة، كل منها مع معاملات فريدة، مساحة مفتاح ذاكرة التخزين المؤقت ضخمة. ضربنا حدود ذاكرة التخزين المؤقت edge في Vercel في الأسبوع الأول واضطررنا إلى أن نكون أكثر إستراتيجية حول الصفحات التي حصلت على قيم expire طويلة. صفحات حركة مرور منخفضة long-tail حصلت على فترات ذاكرة تخزين مؤقت أقصر.
فخ `Date.now()`
أي مكون يستخدم "use cache" الذي يستدعي Date.now() أو new Date() داخل الدالة المخزنة مؤقتاً سيخزن مؤقتاً هذا الوقت. وجدنا هذا في عرض "آخر تحديث" أظهر نفس الوقت لساعات. الإصلاح: نقل منطق حساس للوقت إلى مكون Client أو Server Component غير مخزن مؤقتاً.
حدود ذاكرة التخزين المؤقت المتداخلة
عندما تقوم بتداخل مكونات مخزنة مؤقتاً داخل مكونات مخزنة مؤقتاً أخرى، يكون لدى ذاكرة التخزين المؤقت الداخلية دورة حياة خاصة بها. هذا قوي لكنه محير. أنشأنا اتفاقية فريق: التخزين المؤقت على مستوى الصفحة أو مستوى المكون، وليس كليهما، ما لم يكن هناك سبب واضح.
متى يجب عليك استخدام cacheComponents ومتى لا
استخدمه عندما:
- يكون لديك أكثر من بضع مئات من الصفحات وأوقات بناء ISR مؤلمة
- محتواك له متطلبات نضارة واضحة تختلف حسب القسم
- تحتاج إلى التحكم الدقيق في ما يتم تخزينه مؤقتاً مقابل ما يكون دائماً طازجاً
- أنت تعمل على Vercel أو منصة تدعم طبقات ذاكرة التخزين المؤقت Next.js
- تريد تقليل تكاليف البنية التحتية على المواقع عالية حركة المرور
لا تستخدمه عندما:
- موقعك صغير بما يكفي لأن SSG الكامل يعمل بشكل جيد
- كل صفحة ديناميكية بالكامل (محتوى خاص بالمستخدم في كل مكان)
- أنت لست على منصة استضافة تدعم بنية ذاكرة التخزين المؤقت Next.js
- فريقك جديد على Next.js -- ابدأ بالأساسيات أولاً
إذا كنت تقيّم ما إذا كان مشروعك يحتاج هذا المستوى من التحكم في التخزين المؤقت، أو إذا كان إطار عمل مختلف مثل Astro قد يكون خياراً أفضل لموقع المحتوى الثقيل الخاص بك، فهذا يستحق التفكير فيه قبل الالتزام بترحيل. بالنسبة للمشاريع حيث يأتي المحتوى من عدة مصادر CMS بدون رأس، يعمل نظام cacheTag في Next.js 16 بشكل جميل مع هياكل CMS بدون رأس -- لكل نوع محتوى قناة إبطال خاصة به.
الأسئلة الشائعة
ما هي cacheComponents في Next.js 16؟
cacheComponents هو خيار تكوين تجريبي في Next.js 16 يمكّن توجيه "use cache" لـ Server Components. يتيح لك وضع علامات صريحة على المكونات التي يجب تخزينها مؤقتاً وتحديد ملفات تعريف ذاكرة تخزين مؤقت مخصصة باستخدام cacheLife. إنها التطور المستقر لتوجيه use cache الذي كان تجريبياً في Next.js 15.
كيف تختلف cacheComponents عن ISR (Incremental Static Regeneration)؟
ISR يخزن مؤقتاً الصفحات الكاملة ويعيد التحقق منها على جدول زمني. cacheComponents يتيح لك تخزين مكونات فردية داخل صفحة مؤقتاً، كل منها مع فترات ذاكرة تخزين مؤقت مختلفة. يمكن لصفحة واحدة أن تحتوي على رأس مخزن مؤقتاً لمدة 24 ساعة، ومعلومات منتج مخزنة مؤقتاً لمدة ساعة واحدة، وتسعير لا يتم تخزينه مؤقتاً أبداً. ISR لا يمكنه القيام بذلك -- إنه كل شيء أو لا شيء على مستوى الصفحة.
هل أحتاج إلى أن أكون على Vercel لاستخدام cacheComponents؟
لا، لكن التجربة أفضل على Vercel لأن بنية ذاكرة التخزين المؤقت مدمجة بإحكام. نشرات Next.js المستضافة ذاتياً يمكنها استخدام cacheComponents مع محول ذاكرة التخزين المؤقت في نظام الملفات، لكنك لن تحصل على فوائد توزيع الحواف. المنصات مثل Netlify و Cloudflare تضيف الدعم، لكن اعتباراً من منتصف 2026، تبقى Vercel أكثر التطبيقات اكتمالاً.
كيف أبطل المكونات المخزنة مؤقتاً في Next.js 16؟
تستخدم cacheTag() داخل المكون المخزن مؤقتاً لتعيين العلامات، ثم تستدعي revalidateTag('tag-name') من server action أو route handler أو endpoint webhook. هذا يبطل جميع المكونات المخزنة مؤقتاً مع هذه العلامة. إنه نفس API من Next.js 15، لكنه أكثر فائدة الآن لأنك تضع علامات على مكونات مخزنة مؤقتاً صريحة بدلاً من محاولة إبطال ذاكرة تخزين مؤقت غير واضحة على مستوى الإطار.
هل ستقلل cacheComponents من فاتورة Vercel الخاصة بي؟ يمكن أن تقلل التكاليف بشكل كبير. في حالتنا، انخفضت استدعاءات الدالة بنسبة 54٪ لأن ردود المكونات المخزنة مؤقتاً كانت تُخدم من طبقة ذاكرة التخزين المؤقت بدلاً من استدعاء الدوال بدون خادم. أيضاً توفير وقت البناء يوفر في دقائق البناء. ستختلف النتائج بناءً على أنماط حركة المرور ومعدلات cache hit -- تحقق من حاسبة تسعير Vercel مع استخدامك الحالي.
ماذا يحدث إذا أضفت "use cache" إلى مكون يتلقى دعائم غير قابلة للتسلسل؟
ستحصل على خطأ بناء. توجيه "use cache" ينشئ حد تسلسل، لذا يجب أن تكون جميع الدعائم قابلة للتسلسل (سلاسل، أرقام، كائنات عادية، صفائف). الدوال، عناصر React، مثيلات الفئة، والقيم غير القابلة للتسلسل الأخرى سوف تسبب فشل البناء. أعد هيكلة المكون الخاص بك لقبول دعائم البيانات فقط والتعامل مع التفاعل في مكونات Client الفرعية.
هل يمكنني استخدام cacheComponents مع React Server Components من أطر عمل أخرى؟
لا. cacheComponents هي ميزة خاصة بـ Next.js تبني على Server Components من React. بينما قد يصبح بناء الجملة "use cache" في النهاية معياراً React، فإن ملفات التعريف cacheLife ونظام cacheTag هي APIs Next.js. إذا كنت تستخدم إطار عمل مثل Remix أو إعداد RSC مخصص، ستحتاج إلى استراتيجيات تخزين مؤقت مختلفة.
كم من الوقت يستغرق ترحيل موقع Next.js كبير إلى cacheComponents؟ بالنسبة لموقع 91,000 صفحة مع فريق من 4 مطورين، استغرق الترحيل الكامل 7 أسابيع بما في ذلك الاختبار والمراقبة. قد يتمكن موقع أصغر (أقل من 10,000 صفحة) مع نموذج بيانات أبسط من القيام بذلك في 1-2 أسبوع. تكون التغييرات الفعلية للرمز مباشرة -- يذهب الوقت إلى تدقيق احتياجات التخزين المؤقت الخاصة بك، واختبار تدفقات الإبطال، ومراقبة معدلات cache hit بعد النشر. إذا كنت تفضل عدم الذهاب وحدك، تواصل معنا -- لقد فعلنا هذا عدة مرات الآن.