در کامپوننتهای سروری (Server Components)، دادهها به ازای هر درخواست روی سرور دریافت و رندر میشوند. اما اگر یکی از درخواستهای شما (مثلاً دریافت لیست کامنتها از دیتابیس) کند باشد، کل صفحه بلاک میشود و کاربر تا زمان آماده شدن آخرین بیت از دادهها، با یک صفحه سفید مواجه خواهد شد.
برای حل این مشکل و بهبود زمان لود اولیه، میتوانید صفحه را به تکههای کوچکتر تقسیم کنید و هر تکه را به محض آماده شدن، از سرور به کلاینت بفرستید. به این فرآیند استریمینگ (Streaming) میگویند.
مفهوم استریمینگ و مزایای آن در تجربه کاربری
پیادهسازی لودینگ سراسری برای یک مسیر با فایل loading.js
کنترل مایکرو و نقطهای لودینگها با تگ <Suspense>
طراحی لودینگهای معنادار (Meaningful Loading States)
شما به دو روش میتوانید قابلیت استریمینگ را در اپلیکیشن خود فعال کنید:
استفاده از فایل سراسری loading.js (برای کل صفحه)
استفاده از تگ <Suspense> (برای اجزای خاصی از یک صفحه)
loading.jsراحتترین راه برای استریم کردن یک بخش، ساختن فایلی به نام loading.tsx (یا .js) در پوشه همان مسیر است. به عنوان مثال، برای مدیریت لودینگ مسیر app/blog/page.tsx، کافی است فایل لودینگ را در پوشه app/blog قرار دهید:
// app/blog/loading.tsx
export default function Loading() {
// ظاهر لودینگ سراسری این صفحه را اینجا طراحی کنید
return <div className="animate-pulse">در حال بارگذاری وبلاگ...</div>
}
با این کار، به محض اینکه کاربر روی لینک وبلاگ کلیک کند، ساختار اصلی سایت (Layout) و این کامپوننت لودینگ فورا به او نشان داده میشوند. وقتی رندر صفحه نهایی در سرور به پایان رسید، محتوای اصلی به صورت خودکار جایگزین این لودینگ میشود.
⚠️ یک نکته فنی مهم: در پشت صحنه، Next.js فایل
loading.jsرا درونlayout.jsکامپوننت ریشه شما آشیانهسازی (Nest) کرده و کل فایلpage.jsرا درون یک مرز<Suspense>میپیچد. به همین دلیل، اگر خودِ کامپوننتLayoutبه دادههای کشنشده یا داینامیک زمان اجرا (مثلcookies()یاheaders()) وابسته باشد، فایلloading.jsآن مسیر segment را پوشش نمیدهد و جابهجایی کاربر تا زمان رندر کامل کامپوننت Layout بلاک میشود. برای حل این مشکل، توصیه میشود دسترسیهای داینامیک را به داخل فایلpage.jsببرید یا دور آن بخش داینامیک در کامپوننت Layout، یک مرز<Suspense>دستی بکشید.
<Suspense> با کنترل دقیق (Granular)اگر نمیخواهید کل صفحه پشت لودینگ بماند و ترجیح میدهید بخشهای استاتیک صفحه (مثل هدر و متون ثابت) فوراً لود شوند و فقط بخش دیتا-محور (مثل لیست مقالات) لودینگ داشته باشد، باید از کامپوننت <Suspense> خود ریاکت استفاده کنید:
// app/blog/page.tsx
import { Suspense } from 'react'
import BlogList from '@/components/BlogList'
import BlogListSkeleton from '@/components/BlogListSkeleton'
export default function BlogPage() {
return (
<div className="container">
{/* این بخش استاتیک فورا و بدون معطلی به کلاینت فرستاده و دیده میشود */}
<header className="hero-section">
<h1>به وبلاگ ما خوش آمدید</h1>
<p>جدیدترین مقالات تخصصی را در ادامه مطالعه کنید.</p>
</header>
<main>
{/* فقط این بخش داینامیک استریم میشود و تا زمان آماده شدن، اسکلتون لودینگ را نشان میدهد */}
<Suspense fallback={<BlogListSkeleton />}>
<BlogList />
</Suspense>
</main>
</div>
)
}
با این الگو، بخش هدر بدون وابستگی به سرعت دیتابیس فورا روی مرورگر کاربر نقش میبندد و بخش <BlogList> به محض تکمیل شدن دیتایش روی سرور، قطرهچکانی (Stream) شده و جایگزین اسکلتون میشود.
یک حالت لودینگ فوری (Instant Loading State)، المان بصری واسطی است که بلافاصله پس از کلیک کاربر نمایش داده میشود تا به او اطمینان دهد که اپلیکیشن در حال پردازش است و قفل نکرده است.
برای ایجاد بهترین تجربه کاربری (UX)، پیشنهاد میکنیم لودینگهای معنادار طراحی کنید:
استفاده از اسکلتونها (Skeletons): ساختارهایی کمرنگ و متحرک که شاکله و ابعاد تقریبی محتوای آینده (مثل کارتهای پست، تصاویر یا متون خطی) را شبیهسازی میکنند.
رندر پیشدستانه عناصر ثابت: اگر ترانزیشن صفحه طول میکشد، نمایش بخشهای کوچکی از صفحه بعدی که نیاز به دیتا ندارند (مانند عکس کاور پیشفرض، عنوان ثابت یا دکمهها) حس سرعت بالاتری به کاربر القا میکند.
💡 نکته توسعه: در زمان برنامهنویسی و طراحی، میتوانید به کمک ابزار React Devtools وضعیتهای لودینگ و مرزهای
<Suspense>کامپوننتهای خود را به راحتی تست، شبیهسازی و بازرسی (Inspect) کنید.
استریمینگ (Streaming): شکستن صفحه به بخشهای کوچکتر و ارسال تدریجی آنها به مرورگر برای کاهش زمان انتظار کاربر.
فایل loading.js: روشی سریع برای اعمال لودینگ سراسری روی کل محتوای یک مسیر (Page).
تگ <Suspense>: روشی دقیق و مایکرو برای باز نگه داشتن اجزای استاتیک صفحه و اعمال لودینگ اختصاصی روی کامپوننتهای کند و داینامیک.
بهبود تجربه کاربری: با استفاده از انیمیشنهای اسکلتون (Skeleton Screens) به جای اسپینرهای ساده، سرعت ادراکشده (Perceived Speed) سایت را ارتقا دهید.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://nextjs.org/docs/app