Next.js
مسیریاب app
برنامه تان را بسیازید
بهینه سازی
بارگیری تنبل Lazy

بارگیری تنبل Lazy load

بارگذاری تنبل (Lazy Loading (opens in a new tab)) در Next.js به بهبود عملکرد بارگذاری اولیه برنامه با کاهش مقدار جاوا اسکریپت مورد نیاز برای رندر یک مسیر کمک می‌کند.

این قابلیت به شما امکان می‌دهد بارگذاری کلاینت کامپوننت ها و کتابخانه‌های وارد شده را به تعویق بیندازید و فقط در صورت نیاز آن‌ها را در باندل نرم‌افزاری سمت کلاینت (client bundle) قرار دهید. برای مثال، ممکن است بخواهید بارگذاری یک مودال را تا زمانی که کاربر روی باز کردن آن کلیک نکند، به تعویق بیندازید.

دو روش برای پیاده‌سازی بارگذاری تنبل در Next.js وجود دارد:

  1. استفاده از Dynamic Imports با next/dynamic
  2. استفاده از React.lazy() (opens in a new tab) با Suspense (opens in a new tab)

به طور پیش فرض، کامپوننت‌های سمت سرور (Server Components) به طور خودکار تقسیم کد (code split (opens in a new tab)) می‌شوند و می‌توانید از استریمینگ (streaming) برای ارسال تدریجی قطعات رابط کاربری از سرور به کاربر استفاده کنید. بارگذاری تنبل برای کامپوننت‌های سمت کلاینت اعمال می‌شود.

next/dynamic

next/dynamic ترکیبی از React.lazy() (opens in a new tab) و Suspense (opens in a new tab) است. این قابلیت در دایرکتوری‌های app و pages به صورت یکسان عمل می‌کند تا امکان مهاجرت افزایشی را فراهم آورد.

مثال ها

ایمپورت کردن کامپوننت‌های سمت کاربر

app/page.js
'use client'
 
import { useState } from 'react'
import dynamic from 'next/dynamic'
 
// Client Components:
const ComponentA = dynamic(() => import('../components/A'))
const ComponentB = dynamic(() => import('../components/B'))
const ComponentC = dynamic(() => import('../components/C'), { ssr: false })
 
export default function ClientComponentExample() {
	const [showMore, setShowMore] = useState(false)
 
	return (
		<div>
			{/* Load immediately, but in a separate client bundle */}
			<ComponentA />
 
			{/* Load on demand, only when/if the condition is met */}
			{showMore && <ComponentB />}
			<button onClick={() => setShowMore(!showMore)}>Toggle</button>
 
			{/* Load only on the client side */}
			<ComponentC />
		</div>
	)
}

رد شدن از SSR

هنگام استفاده از React.lazy() و Suspense، کامپوننت‌های سمت کاربر به طور پیش فرض پیش-رندر pre-rendered (SSR) خواهند شد.

اگر می‌خواهید پیش-رندر را برای یک کامپوننت سمت کاربر غیرفعال کنید، می‌توانید از گزینه ssr با مقدار false استفاده کنید:

const ComponentC = dynamic(() => import('../components/C'), { ssr: false })

ایمپورت کردن کامپوننت‌های سمت سرور

اگر یک کامپوننت سمت سرور را به صورت پویا ایمپورت کنید، تنها کامپوننت‌های سمت کاربر که فرزند کامپوننت سمت سرور هستند به صورت تنبل بارگذاری می‌شوند - نه خود کامپوننت سمت سرور.

app/page.js
import dynamic from 'next/dynamic'
 
// Server Component:
const ServerComponent = dynamic(() => import('../components/ServerComponent'))
 
export default function ServerComponentExample() {
	return (
		<div>
			<ServerComponent />
		</div>
	)
}

بارگیری کتابخانه‌های خارجی

کتابخانه‌های خارجی را می‌توان با استفاده از تابع import() (opens in a new tab) به صورت درخواستی بارگذاری کرد. این مثال از کتابخانه خارجی fuse.js برای جستجوی fuzzy استفاده می‌کند. این ماژول تنها پس از تایپ کاربر در ورودی جستجو در سمت کاربر بارگذاری می‌شود.

app/page.js
'use client'
 
import { useState } from 'react'
 
const names = ['Tim', 'Joe', 'Bel', 'Lee']
 
export default function Page() {
	const [results, setResults] = useState()
 
	return (
		<div>
			<input
				type="text"
				placeholder="Search"
				onChange={async (e) => {
					const { value } = e.currentTarget
					// Dynamically load fuse.js
					const Fuse = (await import('fuse.js')).default
					const fuse = new Fuse(names)
 
					setResults(fuse.search(value))
				}}
			/>
			<pre>Results: {JSON.stringify(results, null, 2)}</pre>
		</div>
	)
}

اضافه کردن یک کامپوننت بارگیری سفارشی loading component

app/page.js
import dynamic from 'next/dynamic'
 
const WithCustomLoading = dynamic(
	() => import('../components/WithCustomLoading'),
	{
		loading: () => <p>Loading...</p>,
	}
)
 
export default function Page() {
	return (
		<div>
			{/* The loading component will be rendered while  <WithCustomLoading/> is loading */}
			<WithCustomLoading />
		</div>
	)
}

ایمپورت خروجی‌های نامگذاری شده Importing Named Exports

برای ایمپورت پویای یک خروجی نامگذاری شده named export، می‌توانید آن را از Promise برگشتی توسط تابع import() (opens in a new tab) برگردانید:

components/hello.js
'use client'
 
export function Hello() {
	return <p>Hello!</p>
}
app/page.js
import dynamic from 'next/dynamic'
 
const ClientComponent = dynamic(() =>
	import('../components/hello').then((mod) => mod.Hello)
)