استخدام التخزين المؤقت (use cache)
يسمح لك توجيه use cache
بوضع علامة على مسار أو مكون React أو دالة على أنها قابلة للتخزين المؤقت. يمكن استخدامه في أعلى الملف للإشارة إلى أنه يجب تخزين جميع الصادرات في الملف مؤقتًا، أو مضمنًا في أعلى الدالة أو المكون لتخزين القيمة المرجعة مؤقتًا.
الاستخدام
use cache
هو حاليًا ميزة تجريبية. لتمكينها، أضف خيار useCache
إلى ملف next.config.ts
الخاص بك:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
useCache: true,
},
}
export default nextConfig
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
useCache: true,
},
}
module.exports = nextConfig
معلومة جيدة: يمكن أيضًا تمكين
use cache
باستخدام خيارdynamicIO
.
ثم أضف use cache
على مستوى الملف أو المكون أو الدالة:
// مستوى الملف
'use cache'
export default async function Page() {
// ...
}
// مستوى المكون
export async function MyComponent() {
'use cache'
return <></>
}
// مستوى الدالة
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
كيفية عمل use cache
مفاتيح التخزين المؤقت
يتم إنشاء مفتاح إدخال التخزين المؤقت باستخدام نسخة مسلسلة من مدخلاته، والتي تشمل:
- معرف البناء (يتم إنشاؤه لكل بناء)
- معرف الدالة (معرف فريد وآمن للدالة)
- الوسائط (أو الخصائص) القابلة للتحويل إلى سلسلة (serializable).
الوسائط التي يتم تمريرها إلى الدالة المخزنة مؤقتًا، وكذلك أي قيم تقرأها من النطاق الأصلي تصبح تلقائيًا جزءًا من المفتاح. هذا يعني أنه سيتم إعادة استخدام نفس إدخال التخزين المؤقت طالما كانت المدخلات هي نفسها.
وسائط غير قابلة للتحويل إلى سلسلة
أي وسائط أو خصائص أو قيم مغلقة غير قابلة للتحويل إلى سلسلة ستصبح مراجع داخل الدالة المخزنة مؤقتًا، ويمكن تمريرها فقط دون فحص أو تعديل. لن تصبح هذه القيم غير القابلة للتحويل إلى سلسلة جزءًا من مفتاح التخزين المؤقت وستتم تعبئتها في وقت الطلب.
على سبيل المثال، يمكن أن تأخذ الدالة المخزنة مؤقتًا JSX كخاصية children
وتُرجع <div>{children}</div>
، لكنها لن تكون قادرة على فحص كائن children
الفعلي. هذا يسمح لك بتداخل محتوى غير مخزن مؤقتًا داخل مكون مخزن مؤقتًا.
function CachedComponent({ children }: { children: ReactNode }) {
'use cache'
return <div>{children}</div>
}
function CachedComponent({ children }) {
'use cache'
return <div>{children}</div>
}
قيم الإرجاع
يجب أن تكون القيمة المرجعة من الدالة القابلة للتخزين المؤقت قابلة للتحويل إلى سلسلة. هذا يضمن أنه يمكن تخزين البيانات المؤقتة واستردادها بشكل صحيح.
use cache
في وقت البناء
عند استخدامه في أعلى تخطيط (layout) أو صفحة (page)، سيتم تقديم مقطع المسار مسبقًا، مما يسمح بإعادة التحقق منه لاحقًا.
هذا يعني أنه لا يمكن استخدام use cache
مع واجهات برمجة التطبيقات في وقت الطلب مثل cookies
أو headers
.
use cache
في وقت التشغيل
على الخادم، سيتم تخزين إدخالات التخزين المؤقت للمكونات أو الدوال الفردية في الذاكرة.
ثم على العميل، سيتم تخزين أي محتوى يتم إرجاعه من ذاكرة التخزين المؤقت للخادم في ذاكرة المتصفح لمدة الجلسة أو حتى يتم إعادة التحقق منها.
أثناء إعادة التحقق
بشكل افتراضي، لدى use cache
فترة إعادة تحقق من جانب الخادم تبلغ 15 دقيقة. بينما قد تكون هذه الفترة مفيدة للمحتوى الذي لا يحتاج إلى تحديثات متكررة، يمكنك استخدام واجهات برمجة التطبيقات cacheLife
و cacheTag
لتكوين متى يجب إعادة تحقق إدخالات التخزين المؤقت الفردية.
تتكامل كل من واجهات برمجة التطبيقات هذه عبر طبقات التخزين المؤقت للعميل والخادم، مما يعني أنه يمكنك تكوين دلالات التخزين المؤقت في مكان واحد وتطبيقها في كل مكان.
راجع وثائق API لكل من cacheLife
و cacheTag
لمزيد من المعلومات.
أمثلة
تخزين مسار كامل مؤقتًا باستخدام use cache
لتقديم مسار كامل مسبقًا، أضف use cache
إلى أعلى كلا ملفي layout
و page
. يتم التعامل مع كل من هذه المقاطع كنقاط دخول منفصلة في تطبيقك، وسيتم تخزينها مؤقتًا بشكل مستقل.
'use cache'
export default function Layout({ children }: { children: ReactNode }) {
return <div>{children}</div>
}
'use cache'
export default function Layout({ children }) {
return <div>{children}</div>
}
سيتم توريث سلوك التخزين المؤقت لـ page
من قبل أي مكونات مستوردة ومتداخلة في ملف page
.
'use cache'
async function Users() {
const users = await fetch('/api/users')
// تكرار خلال المستخدمين
}
export default function Page() {
return (
<main>
<Users />
</main>
)
}
'use cache'
async function Users() {
const users = await fetch('/api/users')
// تكرار خلال المستخدمين
}
export default function Page() {
return (
<main>
<Users />
</main>
)
}
معلومة جيدة:
- إذا تمت إضافة
use cache
فقط إلىlayout
أوpage
، فسيتم تخزين هذا المقطع من المسار وأي مكونات مستوردة إليه فقط مؤقتًا.- إذا كان أي من العناصر الفرعية المتداخلة في المسار يستخدم واجهات برمجة التطبيقات الديناميكية، فسيتم استبعاد المسار من التقديم المسبق.
تخزين ناتج مكون مؤقتًا باستخدام use cache
يمكنك استخدام use cache
على مستوى المكون لتخزين أي عمليات جلب أو حسابات تتم داخل هذا المكون. سيتم إعادة استخدام إدخال التخزين المؤقت طالما أن الخصائص المسلسلة تنتج نفس القيمة في كل مثيل.
export async function Bookings({ type = 'haircut' }: BookingsProps) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
interface BookingsProps {
type: string
}
export async function Bookings({ type = 'haircut' }) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
تخزين ناتج دالة مؤقتًا باستخدام use cache
نظرًا لأنه يمكنك إضافة use cache
إلى أي دالة غير متزامنة، فأنت لست مقيدًا بتخزين المكونات أو المسارات فقط. قد ترغب في تخزين طلب شبكة أو استعلام قاعدة بيانات أو عملية حسابية بطيئة مؤقتًا.
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
التداخل
إذا كنت بحاجة إلى تمرير وسائط غير قابلة للتحويل إلى سلسلة إلى دالة قابلة للتخزين المؤقت، يمكنك تمريرها كـ children
. هذا يعني أن مرجع children
يمكن أن يتغير دون التأثير على إدخال التخزين المؤقت.
export default async function Page() {
const uncachedData = await getData()
return (
<CacheComponent>
<DynamicComponent data={uncachedData} />
</CacheComponent>
)
}
async function CacheComponent({ children }: { children: ReactNode }) {
'use cache'
const cachedData = await fetch('/api/cached-data')
return (
<div>
<PrerenderedComponent data={cachedData} />
{children}
</div>
)
}
export default async function Page() {
const uncachedData = await getData()
return (
<CacheComponent>
<DynamicComponent data={uncachedData} />
</CacheComponent>
)
}
async function CacheComponent({ children }) {
'use cache'
const cachedData = await fetch('/api/cached-data')
return (
<div>
<PrerenderedComponent data={cachedData} />
{children}
</div>
)
}
يمكنك أيضًا تمرير إجراءات الخادم (Server Actions) عبر المكونات المخزنة مؤقتًا إلى مكونات العميل دون استدعائها داخل الدالة القابلة للتخزين المؤقت.
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// تنفيذ بعض التحديثات من جانب الخادم
await db.update(...)
}
return <CacheComponent performUpdate={performUpdate} />
}
async function CachedComponent({
performUpdate,
}: {
performUpdate: () => Promise<void>
}) {
'use cache'
// لا تستدع performUpdate هنا
return <ClientComponent action={performUpdate} />
}
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// تنفيذ بعض التحديثات من جانب الخادم
await db.update(...)
}
return <CacheComponent performUpdate={performUpdate} />
}
async function CachedComponent({ performUpdate }) {
'use cache'
// لا تستدع performUpdate هنا
return <ClientComponent action={performUpdate} />
}
'use client'
export default function ClientComponent({
action,
}: {
action: () => Promise<void>
}) {
return <button onClick={action}>تحديث</button>
}
'use client'
export default function ClientComponent({ action }) {
return <button onClick={action}>تحديث</button>
}
دعم المنصة
خيار النشر | مدعوم |
---|---|
خادم Node.js | نعم |
حاوية Docker | نعم |
تصدير ثابت | لا |
المحولات | حسب المنصة |
تعلم كيفية تكوين التخزين المؤقت عند استضافة Next.js ذاتيًا.
تاريخ الإصدارات
الإصدار | التغييرات |
---|---|
v15.0.0 | تم تقديم "use cache" كميزة تجريبية. |