Kodokon kodokon.com

Suspense, lazy, और code splitting

suspension तंत्र, lazy component loading, और bundle splitting में महारत हासिल करें।

9 मिनट · 3 प्रश्न

इस पाठ को Kodokon में खोलें

Suspense एक कम-ज्ञात तंत्र पर निर्भर करता है: एक component जिसके पास अभी तक अपना data या अपना code नहीं है, वह अपनी rendering को निलंबित (suspend) कर देता है। पर्दे के पीछे, वर्तमान implementation एक promise फेंकता है, जिसे React ठीक वैसे ही रोक लेता है जैसे वह किसी error को रोकता। फिर React निकटतम <Suspense> boundary तक ऊपर चलता है, उसका fallback दिखाता है, फिर promise के resolve होने पर subtree के render को दोबारा चलाता है। यह एक implementation विवरण है (कभी भी खुद promise न फेंकें), लेकिन यह सभी अवलोकनीय व्यवहार को समझाता है: boundary async काम के लिए एक declarative catch की तरह काम करती है। ऐतिहासिक उपयोग-मामला React.lazy के साथ code splitting है।

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

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

function Dashboard() {
  return (
    <Suspense fallback={<Spinner />}>
      <Chart points={data} />
    </Suspense>
  );
}
Chart का code केवल उसके पहले render पर डाउनलोड होता है।

lazy एक ऐसे function की अपेक्षा करता है जो एक promise लौटाए जो default export वाले किसी module में resolve हो। Splitting स्वयं bundler का काम है: हर dynamic import() एक split point बन जाता है और एक अलग chunk उत्पन्न करता है, जो माँग पर लोड होता है। असली codebases में एक आम सूक्ष्मता: आपके components अक्सर named exports होते हैं। तब आपको module को उड़ते हुए अनुकूलित करना पड़ता है।

JAVASCRIPT
const Chart = lazy(() =>
  import('./charts').then((module) => ({
    default: module.Chart,
  }))
);
किसी named export को React.lazy अनुबंध के अनुरूप ढालना।

Production में मुश्किल हिस्सा: किसी navigation के दौरान, पहले से प्रदर्शित content फिर से suspend हो सकता है (नया route, नया chunk) और अचानक fallback से बदल दिया जा सकता है। React 18 से, startTransition में लपेटा गया एक update इस व्यवहार को बदल देता है: React पिछले interface को स्क्रीन पर रखता है जबकि नया render पृष्ठभूमि में suspend होता है, और fallback केवल उस content के लिए दिखाता है जो कभी प्रकट नहीं हुआ। Boundaries गहराई में भी संयोजित होती हैं: कई nested <Suspense> boundaries आपको interface को क्षेत्र-दर-क्षेत्र प्रकट करने देती हैं, वैश्विक skeleton से लेकर विवरण तक।

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.
एक transition navigation के दौरान fallback पर वापस गिरने से बचाता है।

ज्ञान जांच

सुनिश्चित करें कि आपको इस पाठ के मुख्य बिंदु याद हैं।

  1. React.lazy को दिया गया function क्या लौटाना चाहिए?
    • सीधे एक React component
    • एक promise जो default export वाले किसी module में resolve हो
    • एक object { component, loading }
    • फ़ाइल path वाली एक string
  2. जब कोई navigation suspend होता है तो पहले से प्रदर्शित content को fallback से बदले जाने से कैसे रोकें?
    • state update को startTransition में लपेटें
    • Suspense boundary को fallback={null} पास करें
    • navigation को टालने के लिए useEffect का उपयोग करें
    • मूल Suspense boundary को हटा दें
  3. code को अलग-अलग chunks में बाँटने का काम वास्तव में कौन करता है?
    • React, commit phase के दौरान
    • browser, HTTP cache के माध्यम से
    • bundler, हर dynamic import() से