Next.js में डाइनैमिक इंपोर्ट के साथ कोड बांटना

कोड को अलग-अलग हिस्सों में बांटने और स्मार्ट लोडिंग की रणनीतियों की मदद से, अपने Next.js ऐप्लिकेशन को तेज़ करने का तरीका.

आपको क्या सीखने को मिलेगा?

इस पोस्ट में, अलग-अलग तरह के कोड को अलग-अलग हिस्सों में बांटने के बारे में बताया गया है. साथ ही, Next.js ऐप्लिकेशन की स्पीड बढ़ाने के लिए, डाइनैमिक इंपोर्ट का इस्तेमाल करने का तरीका भी बताया गया है.

रूट और कॉम्पोनेंट के आधार पर कोड का बंटवारा

डिफ़ॉल्ट रूप से, Next.js आपके JavaScript को हर रूट के लिए अलग-अलग हिस्सों में बांट देता है. जब उपयोगकर्ता आपका ऐप्लिकेशन लोड करते हैं, तो Next.js सिर्फ़ शुरुआती रूट के लिए ज़रूरी कोड भेजता है. जब उपयोगकर्ता ऐप्लिकेशन पर नेविगेट करते हैं, तो वे दूसरे रास्तों से जुड़े चंक फ़ेच करते हैं. रूट के हिसाब से कोड को अलग-अलग करने से, एक साथ पार्स और कंपाइल की जाने वाली स्क्रिप्ट की संख्या कम हो जाती है. इससे पेज लोड होने में कम समय लगता है.

रूट के हिसाब से कोड को अलग-अलग हिस्सों में बांटने की सुविधा, डिफ़ॉल्ट रूप से अच्छी होती है. हालांकि, कॉम्पोनेंट लेवल पर कोड को अलग-अलग हिस्सों में बांटकर, लोड करने की प्रोसेस को और ऑप्टिमाइज़ किया जा सकता है. अगर आपके ऐप्लिकेशन में बड़े कॉम्पोनेंट हैं, तो उन्हें अलग-अलग हिस्सों में बांटना एक अच्छा आइडिया है. इस तरह, बड़े कॉम्पोनेंट को तब लोड किया जा सकता है, जब वे ज़रूरी न हों या सिर्फ़ कुछ उपयोगकर्ता इंटरैक्शन (जैसे, बटन पर क्लिक करना) पर रेंडर हों.

Next.js, डाइनैमिक import() के साथ काम करता है. इससे, JavaScript मॉड्यूल (इनमें React कॉम्पोनेंट भी शामिल हैं) को डाइनैमिक तरीके से इंपोर्ट किया जा सकता है. साथ ही, हर इंपोर्ट को अलग-अलग चंक के तौर पर लोड किया जा सकता है. इससे, आपको कॉम्पोनेंट-लेवल पर कोड को अलग-अलग हिस्सों में बांटने की सुविधा मिलती है. साथ ही, संसाधन लोड करने की प्रोसेस को कंट्रोल करने में भी मदद मिलती है, ताकि उपयोगकर्ता सिर्फ़ उस हिस्से का कोड डाउनलोड कर सकें जिसे वे देख रहे हैं. Next.js में, ये कॉम्पोनेंट डिफ़ॉल्ट रूप से सर्वर साइड रेंडर किए जाते हैं (एसएसआर).

डाइनैमिक इंपोर्ट की सुविधा इस्तेमाल करने का उदाहरण

इस पोस्ट में, सैंपल ऐप्लिकेशन के कई वर्शन शामिल हैं. इनमें एक बटन वाला आसान पेज शामिल है. बटन पर क्लिक करने पर, आपको एक प्यारा सा पिल्ला दिखता है. ऐप्लिकेशन के हर वर्शन को देखते समय, आपको पता चलेगा कि डाइनैमिक इंपोर्ट, स्टैटिक इंपोर्ट से कैसे अलग होते हैं और इनका इस्तेमाल कैसे किया जाता है.

ऐप्लिकेशन के पहले वर्शन में, पिल्ला components/Puppy.js में रहता है. पेज पर पिल्ला दिखाने के लिए, ऐप्लिकेशन स्टैटिक इंपोर्ट स्टेटमेंट की मदद से, index.js में Puppy कॉम्पोनेंट इंपोर्ट करता है:

import Puppy from "../components/Puppy";

Next.js, ऐप्लिकेशन को कैसे बंडल करता है, यह देखने के लिए DevTools में नेटवर्क ट्रेस की जांच करें:

  1. साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन फ़ुलस्क्रीन दबाएं.

  2. DevTools खोलने के लिए, `Control+Shift+J` दबाएं. Mac पर, `Command+Option+J` दबाएं.

  3. नेटवर्क टैब पर क्लिक करें.

  4. कैश मेमोरी की सुविधा बंद करें चेकबॉक्स को चुनें.

  5. पेज को फिर से लोड करें.

पेज लोड करने पर, Puppy.js कॉम्पोनेंट के साथ-साथ सभी ज़रूरी कोड, index.js में बंडल हो जाते हैं:

DevTools के नेटवर्क टैब में छह JavaScript फ़ाइलें दिख रही हैं: index.js, app.js, webpack.js, main.js, 0.js, और dll (डाइनैमिक-लिंक लाइब्रेरी) फ़ाइल.

मुझ पर क्लिक करें बटन दबाने पर, नेटवर्क टैब में सिर्फ़ पिल्ला के जेपीईजी फ़ोटो का अनुरोध जोड़ा जाता है:

बटन पर क्लिक करने के बाद, DevTools का नेटवर्क टैब, जिसमें वे छह JavaScript फ़ाइलें और एक इमेज दिख रही हैं.

इस तरीके का एक नुकसान यह है कि भले ही उपयोगकर्ता पिल्ला देखने के लिए बटन पर क्लिक न करें, फिर भी उन्हें Puppy कॉम्पोनेंट लोड करना होगा, क्योंकि यह index.js में शामिल है. इस छोटे उदाहरण में, यह कोई बड़ी बात नहीं है. हालांकि, असल दुनिया के ऐप्लिकेशन में, ज़रूरत पड़ने पर ही बड़े कॉम्पोनेंट लोड करने से काफ़ी फ़ायदा होता है.

अब ऐप्लिकेशन का दूसरा वर्शन देखें, जिसमें स्टैटिक इंपोर्ट को डाइनैमिक इंपोर्ट से बदल दिया गया है. Next.js में next/dynamic शामिल है. इसकी मदद से, Next में किसी भी कॉम्पोनेंट के लिए डाइनैमिक इंपोर्ट का इस्तेमाल किया जा सकता है:

import Puppy from "../components/Puppy";
import dynamic from "next/dynamic";

// ...

const Puppy = dynamic(import("../components/Puppy"));

नेटवर्क ट्रेस की जांच करने के लिए, पहले उदाहरण में दिया गया तरीका अपनाएं.

ऐप्लिकेशन को पहली बार लोड करने पर, सिर्फ़ index.js डाउनलोड होता है. इस बार यह 0.5 केबी छोटा है (37.9 केबी से 37.4 केबी हो गया), क्योंकि इसमें Puppy कॉम्पोनेंट का कोड शामिल नहीं है:

DevTools नेटवर्क में, index.js को छोड़कर वही छह JavaScript फ़ाइलें दिख रही हैं. हालांकि, index.js अब 0.5 केबी छोटी हो गई है.

Puppy कॉम्पोनेंट अब एक अलग चंक, 1.js में है. यह सिर्फ़ तब लोड होता है, जब बटन को दबाया जाता है:

बटन पर क्लिक करने के बाद, DevTools का नेटवर्क टैब. इसमें, फ़ाइल सूची में सबसे नीचे जोड़ी गई 1.js फ़ाइल और इमेज दिख रही है.

असल दुनिया के ऐप्लिकेशन में, कॉम्पोनेंट अक्सर काफ़ी बड़े होते हैं. इन्हें लेज़ी लोड करने से, आपके शुरुआती JavaScript पेलोड को सैकड़ों किलोबाइट तक छोटा किया जा सकता है.

कस्टम लोडिंग इंडिकेटर के साथ डाइनैमिक इंपोर्ट

संसाधनों को धीरे-धीरे लोड करने पर, लोड होने में लगने वाले समय के बारे में बताने वाला इंडिकेटर देना एक अच्छा तरीका है. Next.js में, dynamic() फ़ंक्शन में एक और आर्ग्युमेंट देकर ऐसा किया जा सकता है:

const Puppy = dynamic(() => import("../components/Puppy"), {
  loading: () => <p>Loading...</p>
});

लोडिंग इंडिकेटर को काम करते हुए देखने के लिए, DevTools में धीमे नेटवर्क कनेक्शन का सिम्युलेशन करें:

  1. साइट की झलक देखने के लिए, ऐप्लिकेशन देखें दबाएं. इसके बाद, फ़ुलस्क्रीन फ़ुलस्क्रीन दबाएं.

  2. DevTools खोलने के लिए, `Control+Shift+J` दबाएं. Mac पर, `Command+Option+J` दबाएं.

  3. नेटवर्क टैब पर क्लिक करें.

  4. कैश मेमोरी की सुविधा बंद करें चेकबॉक्स को चुनें.

  5. थ्रॉटलिंग ड्रॉप-डाउन सूची में, फास्ट 3G चुनें.

  6. मुझ पर क्लिक करें बटन दबाएं.

अब बटन पर क्लिक करने पर, कॉम्पोनेंट को लोड होने में कुछ समय लगता है. इस दौरान, ऐप्लिकेशन "लोड हो रहा है…" मैसेज दिखाता है.

टेक्स्ट वाली डार्क स्क्रीन

एसएसआर के बिना डाइनैमिक इंपोर्ट

अगर आपको किसी कॉम्पोनेंट को सिर्फ़ क्लाइंट साइड पर रेंडर करना है, जैसे कि चैट विजेट, तो ssr विकल्प को false पर सेट करें:

const Puppy = dynamic(() => import("../components/Puppy"), {
  ssr: false,
});

नतीजा

डाइनैमिक इंपोर्ट की सुविधा के साथ, Next.js आपको कॉम्पोनेंट-लेवल पर कोड को अलग-अलग करने की सुविधा देता है. इससे आपके JavaScript पेलोड कम हो सकते हैं और ऐप्लिकेशन लोड होने में लगने वाला समय कम हो सकता है. सभी कॉम्पोनेंट, डिफ़ॉल्ट रूप से सर्वर साइड पर रेंडर किए जाते हैं. हालांकि, ज़रूरत पड़ने पर इस विकल्प को बंद किया जा सकता है.