كيفية التحميل المؤجل للمكونات والمكتبات على جانب العميل

يساعد التحميل المتأخر في Next.js على تحسين أداء التحميل الأولي للتطبيق عن طريق تقليل كمية JavaScript المطلوبة لعرض مسار.

يسمح لك بتأجيل تحميل المكونات من جانب العميل (Client Components) والمكتبات المستوردة، وتضمينها فقط في حزمة العميل عند الحاجة إليها. على سبيل المثال، قد ترغب في تأجيل تحميل نافذة منبثقة حتى ينقر المستخدم لفتحها.

هناك طريقتان لتنفيذ التحميل المتأخر في Next.js:

  1. استخدام الاستيراد الديناميكي مع next/dynamic
  2. استخدام React.lazy() مع Suspense

بشكل افتراضي، يتم تقسيم الكود تلقائيًا للمكونات من جانب الخادم (Server Components)، ويمكنك استخدام البث التدريجي لإرسال أجزاء واجهة المستخدم تدريجيًا من الخادم إلى العميل. ينطبق التحميل المتأخر على المكونات من جانب العميل (Client Components).

next/dynamic

next/dynamic هو مزيج من React.lazy() و Suspense. يعمل بنفس الطريقة في دليل app و pages للسماح بالهجرة التدريجية.

أمثلة

باستخدام next/dynamic، لن يتم تضمين مكون الرأس في حزمة JavaScript الأولية للصفحة. ستقوم الصفحة بعرض fallback الخاص بـ Suspense أولاً، متبوعًا بمكون Header عند حل حد Suspense.

import dynamic from 'next/dynamic'

const DynamicHeader = dynamic(() => import('../components/header'), {
  loading: () => <p>Loading...</p>,
})

export default function Home() {
  return <DynamicHeader />
}

معلومة مفيدة: في import('path/to/component')، يجب كتابة المسار بشكل صريح. لا يمكن أن يكون سلسلة قوالب ولا متغيرًا. بالإضافة إلى ذلك، يجب أن تكون import() داخل استدعاء dynamic() لكي تتمكن Next.js من مطابقة حزم webpack / معرّفات الوحدات مع استدعاء dynamic() المحدد وتحميلها مسبقًا قبل التقديم. لا يمكن استخدام dynamic() داخل عرض React لأنه يجب وضعه في المستوى العلوي للوحدة لكي يعمل التحميل المسبق، مشابهًا لـ React.lazy.

مع التصديرات المسماة

لاستيراد تصدير مسما بشكل ديناميكي، يمكنك إعادته من Promise الذي تُرجعها import():

components/hello.js
export function Hello() {
  return <p>Hello!</p>
}

// pages/index.js
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() =>
  import('../components/hello').then((mod) => mod.Hello)
)

بدون SSR

لتحميل مكون ديناميكيًا على جانب العميل، يمكنك استخدام خيار ssr لتعطيل التقديم من جانب الخادم. هذا مفيد إذا كانت تبعية خارجية أو مكون يعتمد على واجهات برمجة المتصفح مثل window.

'use client'

import dynamic from 'next/dynamic'

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

مع المكتبات الخارجية

يستخدم هذا المثال المكتبة الخارجية fuse.js للبحث الضبابي. يتم تحميل الوحدة فقط في المتصفح بعد إدخال المستخدم في حقل البحث.

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
          // تحميل 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>
  )
}