هنگام استفاده از قابلیت کامپوننتهای کش (Cache Components) در Next.js، شناخت ماهیت عملیاتها بسیار حیاتی است. فریمورک Next.js عملیاتها را به دو دسته کلی تقسیم میکند: نامعین (Non-deterministic) که در هر بار اجرا خروجی متفاوتی دارند، و معین (Deterministic) که با ورودی یکسان، همیشه خروجی ثابتی تولید میکنند.
نحوه مدیریت فرآیندهای نامعین (مانند زمان فعلی یا تولید UUID) در کامپوننتهای کش
کاربرد متد connection() برای به تعویق انداختن اجرای کد تا زمان درخواست کاربر
چگونگی برخورد Next.js با عملیاتهای معین (مانند خواندن فایلهای محلی استاتیک) در مرحله پیشرندرینگ
دستوراتی مثل Math.random()، Date.now()، یا crypto.randomUUID() در هر ثانیه یا هر بار اجرا، مقدار کاملاً جدیدی تولید میکنند. از آنجا که سیستم کش کامپوننتها به دنبال دیتای قابل پیشبینی است، شما باید استراتژی خود را برای برخورد با این توابع صراحتاً مشخص کنید. برای مدیریت این لایه دو راهکار پیش رو دارید:
اگر نیاز دارید این مقدار نامعین، دقیقاً در همان لحظه درخواست کاربر (Request time) تولید شود، باید با فراخوانی متد connection() از پکیج next/server به Next.js بفهمانید که اجرای این بخش را تا زمان اتصال کاربر به تعویق بیندازد. به دلیل داینامیک شدن این فرآیند، کامپوننت حتماً باید درون تگ <Suspense> قرار گیرد:
// page.tsx
import { connection } from 'next/server'
import { Suspense } from 'react'
async function UniqueContent() {
// ۱. بررسی اتصال و به تعویق انداختن اجرا تا زمان درخواست واقعی کاربر
await connection()
// ۲. این عملیات نامعین حالا با خیال راحت در زمان درخواست اجرا میشود
const uuid = crypto.randomUUID()
return <p>شناسه درخواست شما: {uuid}</p>
}
export default function Page() {
return (
<Suspense fallback={<p>در حال تولید شناسه...</p>}>
<UniqueContent />
</Suspense>
)
}
اگر میخواهید مقدار نامعین فقط یکبار (مثلاً در زمان بیلد پروژه یا اولین رندر) تولید شود و همه کاربران تا زمان انقضای کش (Revalidation) همان مقدار ثابت را ببینند، کافی است دایرکتیو 'use cache' را به کامپوننت اضافه کنید:
// page.tsx
export default async function Page() {
'use cache' // فعالسازی کش روی کل کامپوننت
// این UUID فقط یکبار تولید و کَش میشود؛ تمام کاربران یک دیتای مشترک میبینند
const buildId = crypto.randomUUID()
return <p>شناسه نسخه بیلد: {buildId}</p>
}
عملیاتهایی مانند کدهای محاسباتی خالص (Pure Computations)، وارد کردن ماژولها (import)، یا عملیاتهای خواندن و نوشتن همگام فایلها (Synchronous I/O)، عملیاتهای معین محسوب میشوند.
Next.js میداند خروجی این کدها تغییر نمیکند؛ در نتیجه، تمام این پردازشها را در همان مرحله پیشرندرینگ (Prerendering) در سمت سرور انجام داده و خروجی رندر شدهی HTML آنها را مستقیماً درون پوسته استاتیک اصلی (Static HTML Shell) جای میدهد. با این کار، در زمان درخواست کاربر هیچ پردازش اضافهای روی سرور رخ نمیدهد:
// page.tsx
import fs from 'node:fs'
export default async function Page() {
// این عملیاتهای همگام در مرحله Prerendering کامپایل شده و در خروجی استاتیک ذخیره میشوند
const content = fs.readFileSync('./config.json', 'utf-8')
const constants = await import('./constants.json')
const processed = JSON.parse(content).items.map((item) => item.value * 2)
return (
<div>
<h1>{constants.appName}</h1>
<ul>
{processed.map((value, i) => (
<li key={i}>{value}</li>
))}
</ul>
</div>
)
}
💡 یک نکته بسیار کلیدی برای دیتابیسهای همگام: > این رفتار معین شامل کوئری زدن به دیتابیسهای تعبیهشده (Embedded) که API همگام دارند (مثل
better-sqlite3یا ماژول بومیnode:sqliteدر نودجیاس) نیز میشود. این یعنی دیتای آنها نیز در زمان بیلد ثابت میشود! > اگر از این ابزارهای همگام استفاده میکنید اما نیاز دارید اطلاعات دیتابیس در هر درخواست کاربر به صورت زنده خواند شود، باید دقیقاً قبل از اجرای کوئری، متدconnection()را صدا بزنید.
عملیاتهای نامعین (Math.random یا Date.now) به مدیریت صریح در کامپوننتهای کش نیاز دارند.
متد connection() فرآیند رندر کامپوننت را تا زمان درخواست واقعی کاربر به تعویق میاندازد و استفاده از آن نیازمند تگ <Suspense> است.
با اعمال دایرکتیو "use cache"، مقادیر نامعین تبدیل به یک دیتای ثابت و مشترک برای تمام کاربران میشوند.
عملیاتهای معین و همگام (مثل fs.readFileSync) در فاز پیشرندرینگ پردازش شده و به بخشی از پوسته استاتیک HTML تبدیل میشوند.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://nextjs.org/docs/app