Kodokon kodokon.com

Suspense وlazy وتقسيم الشيفرة

أتقِن آلية التعليق، وتحميل المكوّنات الكسول، وتقسيم الحزمة.

9 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

يعتمد Suspense على آلية قليلة الشهرة: المكوّن الذي لا يملك بعدُ بياناته أو شيفرته يُعلّق عرضه. تحت الغطاء، تُطلق التطبيقة الحالية وعداً يعترضه React تماماً كما يعترض خطأً. عندئذٍ يصعد React إلى أقرب حدّ <Suspense>، فيعرض fallback الخاص به، ثم يعيد عرض الشجرة الفرعية بمجرّد أن يُحلّ الوعد. إنه تفصيل من تفاصيل التطبيق (لا تُطلق وعداً بنفسك أبداً)، لكنه يفسّر كل السلوك القابل للملاحظة: يعمل الحدّ عمل catch تصريحي للعمل غير المتزامن. الاستعمال التاريخي هو تقسيم الشيفرة بواسطة React.lazy.

JSX
import { lazy, Suspense } from 'react';

const Chart = lazy(() => import('./Chart'));

function Dashboard() {
  return (
    <Suspense fallback={<Spinner />}>
      <Chart points={data} />
    </Suspense>
  );
}
شيفرة Chart لا تُنزَّل إلا عند أول عرض له.

يتوقّع lazy دالة تُرجِع وعداً يُحَلّ إلى وحدة ذات تصدير default. أمّا التقسيم نفسه فهو مهمّة أداة الحزم: كل import() ديناميكي يصبح نقطة تقسيم وينتج قطعة منفصلة تُحمَّل عند الطلب. دقيقة شائعة في قواعد الشيفرة الحقيقية: كثيراً ما تكون مكوّناتك تصديرات مُسمّاة. عندئذٍ عليك تكييف الوحدة أثناء التشغيل.

JAVASCRIPT
const Chart = lazy(() =>
  import('./charts').then((module) => ({
    default: module.Chart,
  }))
);
تكييف تصدير مُسمّى مع عقد React.lazy.

الجزء الشائك في الإنتاج: أثناء التنقّل، يمكن لمحتوى معروض فعلاً أن يُعلَّق من جديد (مسار جديد، قطعة جديدة) فيُستبدَل فجأةً بالـ fallback. منذ React 18، يغيّر تحديث مغلّف بـ startTransition هذا السلوك: يُبقي React الواجهة السابقة على الشاشة بينما يُعلَّق العرض الجديد في الخلفية، ولا يعرض الـ fallback إلا للمحتوى الذي لم يُكشَف قطّ. كما تتركّب الحدود في العمق: عدّة حدود <Suspense> متداخلة تتيح كشف الواجهة منطقةً منطقةً، من الهيكل العام نزولاً إلى التفاصيل.

JSX
const [isPending, startTransition] = useTransition();

function openTab(nextTab) {
  startTransition(() => {
    setTab(nextTab);
  });
}
// The current tab stays visible while the new
// one loads, instead of dropping back to the fallback.
الانتقال يتجنّب السقوط إلى الـ fallback أثناء التنقّل.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. ماذا يجب أن تُرجِع الدالة المُمرَّرة إلى React.lazy؟
    • مكوّن React مباشرةً
    • وعداً يُحَلّ إلى وحدة ذات تصدير default
    • كائناً { component, loading }
    • سلسلة نصية تحتوي على مسار الملف
  2. كيف تمنع استبدال محتوى معروض فعلاً بالـ fallback عند تعليق التنقّل؟
    • غلّف تحديث الحالة بـ startTransition
    • مرّر fallback={null} إلى حدّ Suspense
    • استعمل useEffect لتأخير التنقّل
    • احذف حدّ Suspense الأب
  3. مَن الذي ينفّذ فعلاً تقسيم الشيفرة إلى قطع منفصلة؟
    • React، أثناء مرحلة الإيداع
    • المتصفّح، عبر ذاكرة الـ HTTP المؤقّتة
    • أداة الحزم، انطلاقاً من كل import() ديناميكي