Next.js में, तीसरे पक्ष की स्क्रिप्ट लोड होने के लिए ऑप्टिमाइज़ करना

Next.js के स्क्रिप्ट कॉम्पोनेंट के पीछे के विज़न को समझें. यह कॉम्पोनेंट, तीसरे पक्ष की स्क्रिप्ट को लोड करने की प्रोसेस को ऑप्टिमाइज़ करने के लिए, पहले से मौजूद समाधान उपलब्ध कराता है.

Leena Sohoni
Leena Sohoni

मोबाइल और डेस्कटॉप पर दिखाई जाने वाली वेबसाइटों से मिलने वाले करीब 45% अनुरोध, तीसरे पक्ष के अनुरोध होते हैं. इनमें से 33% स्क्रिप्ट होती हैं. तीसरे पक्ष की स्क्रिप्ट के साइज़, इंतज़ार के समय, और लोड होने से, साइट की परफ़ॉर्मेंस पर काफ़ी असर पड़ सकता है. Next.js स्क्रिप्ट कॉम्पोनेंट में, पहले से ही सबसे सही तरीके और डिफ़ॉल्ट सेटिंग मौजूद होती हैं. इनकी मदद से, डेवलपर अपने ऐप्लिकेशन में तीसरे पक्ष की स्क्रिप्ट जोड़ सकते हैं. साथ ही, परफ़ॉर्मेंस से जुड़ी संभावित समस्याओं को आसानी से हल कर सकते हैं.

तीसरे पक्ष की स्क्रिप्ट और परफ़ॉर्मेंस पर उनका असर

तीसरे पक्ष की स्क्रिप्ट की मदद से, वेब डेवलपर सामान्य सुविधाओं को लागू करने के लिए, मौजूदा समाधानों का फ़ायदा ले सकते हैं. साथ ही, डेवलपमेंट में लगने वाले समय को कम कर सकते हैं. हालांकि, इन स्क्रिप्ट को बनाने वाले लोगों को आम तौर पर, वेबसाइट की परफ़ॉर्मेंस पर पड़ने वाले असर को ध्यान में रखने के लिए कोई इंसेंटिव नहीं मिलता. ये स्क्रिप्ट, इनका इस्तेमाल करने वाले डेवलपर के लिए भी ब्लैकबॉक्स की तरह होती हैं.

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

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

रेंडर ब्लॉक करने वाले संसाधनों को हटाने और तीसरे पक्ष के कोड का इस्तेमाल कम से कम करने के लिए, Lighthouse ऑडिट

अपने पेज के रिसॉर्स लोड होने के क्रम पर ध्यान देना ज़रूरी है, ताकि ज़रूरी रिसॉर्स लोड होने में देरी न हो और ग़ैर-ज़रूरी रिसॉर्स, ज़रूरी रिसॉर्स को ब्लॉक न करें.

तीसरे पक्ष के असर को कम करने के लिए सबसे सही तरीके मौजूद हैं. हालांकि, हो सकता है कि हर किसी को यह न पता हो कि इस्तेमाल किए जाने वाले हर तीसरे पक्ष के लिए, उन्हें कैसे लागू किया जाए. यह मुश्किल हो सकता है, क्योंकि:

  • औसतन, वेबसाइटें मोबाइल और डेस्कटॉप पर 21 से 23 अलग-अलग तीसरे पक्षों का इस्तेमाल करती हैं. इनमें स्क्रिप्ट भी शामिल हैं. हर तरह के कैंपेन के लिए, इस्तेमाल और सुझाव अलग-अलग हो सकते हैं.
  • तीसरे पक्ष के कई टैग लागू करने का तरीका इस बात पर निर्भर करता है कि किसी खास फ़्रेमवर्क या यूज़र इंटरफ़ेस (यूआई) लाइब्रेरी का इस्तेमाल किया गया है या नहीं.
  • तीसरे पक्ष की नई लाइब्रेरी अक्सर लॉन्च की जाती हैं.
  • एक ही तीसरे पक्ष से जुड़ी कारोबार की अलग-अलग ज़रूरतों की वजह से, डेवलपर के लिए इसके इस्तेमाल को स्टैंडर्ड बनाना मुश्किल हो जाता है.

तीसरे पक्ष की स्क्रिप्ट पर Aurora का फ़ोकस

Aurora, ओपन सोर्स वेब फ़्रेमवर्क और टूल के साथ मिलकर काम करता है. इसका मकसद, डेवलपर को बेहतर डिफ़ॉल्ट सेटिंग और खास टूल उपलब्ध कराना है. इससे डेवलपर को उपयोगकर्ता अनुभव के पहलुओं को बेहतर बनाने में मदद मिलती है. जैसे, परफ़ॉर्मेंस, सुलभता, सुरक्षा, और मोबाइल के लिए तैयार होना. साल 2021 में, हमारा फ़ोकस फ़्रेमवर्क स्टैक को उपयोगकर्ता अनुभव और Core Web Vitals मेट्रिक को बेहतर बनाने में मदद करने पर था.

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

किसी ऐप्लिकेशन में इस्तेमाल की गई तीसरे पक्ष की स्क्रिप्ट को मुख्य थ्रेड से ब्लॉक करने की समस्या को हल करने के लिए, हमने स्क्रिप्ट कॉम्पोनेंट बनाया है. इस कॉम्पोनेंट में सीक्वेंसिंग की सुविधाएं शामिल हैं. इससे डेवलपर को तीसरे पक्ष की स्क्रिप्ट लोड करने के लिए बेहतर कंट्रोल मिलते हैं.

फ़्रेमवर्क कॉम्पोनेंट के बिना, तीसरे पक्ष की स्क्रिप्ट को क्रम में लगाना

रेंडर-ब्लॉकिंग स्क्रिप्ट के असर को कम करने के लिए, उपलब्ध दिशा-निर्देशों में तीसरे पक्ष की स्क्रिप्ट को बेहतर तरीके से लोड करने और क्रम में लगाने के ये तरीके बताए गए हैं:

  1. <script> टैग के साथ async या defer एट्रिब्यूट का इस्तेमाल करें. इससे ब्राउज़र को दस्तावेज़ पार्सर को ब्लॉक किए बिना, तीसरे पक्ष की गै़र-ज़रूरी स्क्रिप्ट लोड करने का निर्देश मिलता है. ऐसी स्क्रिप्ट जो पेज के शुरुआती लोड या उपयोगकर्ता के पहले इंटरैक्शन के लिए ज़रूरी नहीं हैं उन्हें गैर-ज़रूरी माना जा सकता है.

       <script src="https://example.com/script1.js" defer></script>
       <script src="https://example.com/script2.js" async></script>
    
  2. प्रीकनेक्ट और डीएनएस-प्रीफ़ेच का इस्तेमाल करके, ज़रूरी ऑरिजिन के साथ पहले से कनेक्शन बनाएं. इससे ज़रूरी स्क्रिप्ट को पहले डाउनलोड किया जा सकता है.

       <head>
           <link rel="preconnect" href="http://PreconnThis.com">
           <link rel="dns-prefetch" href="http://PrefetchThis.com">
       </head>
    
  3. तीसरे पक्ष के संसाधनों और एम्बेड किए गए कॉन्टेंट को लेज़ी-लोड करें. ऐसा तब करें, जब मुख्य पेज का कॉन्टेंट लोड हो जाए या जब उपयोगकर्ता पेज के उस हिस्से तक स्क्रोल करे जहां वे शामिल हैं.

Next.js स्क्रिप्ट कॉम्पोनेंट

Next.js स्क्रिप्ट कॉम्पोनेंट, स्क्रिप्ट को क्रम से लगाने के लिए ऊपर बताए गए तरीकों को लागू करता है. साथ ही, डेवलपर को स्क्रिप्ट लोड करने की रणनीति तय करने के लिए एक टेंप्लेट उपलब्ध कराता है. सही रणनीति तय करने के बाद, यह अन्य ज़रूरी संसाधनों को ब्लॉक किए बिना, बेहतर तरीके से लोड होगी.

स्क्रिप्ट कॉम्पोनेंट, एचटीएमएल <script> टैग पर आधारित होता है. यह रणनीति एट्रिब्यूट का इस्तेमाल करके, तीसरे पक्ष की स्क्रिप्ट के लिए लोड होने की प्राथमिकता सेट करने का विकल्प देता है.

// Example for beforeInteractive:
<Script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" />

// Example for afterInteractive (default):
<Script src="https://example.com/samplescript.js" />

// Example for lazyonload:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" />

रणनीति एट्रिब्यूट की तीन वैल्यू हो सकती हैं.

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

  2. afterInteractive: यह लागू की गई डिफ़ॉल्ट रणनीति है. यह defer एट्रिब्यूट वाली स्क्रिप्ट को लोड करने के बराबर है. इसका इस्तेमाल उन स्क्रिप्ट के लिए किया जाना चाहिए जिन्हें ब्राउज़र, पेज के इंटरैक्टिव होने के बाद चला सकता है. उदाहरण के लिए, आंकड़ों से जुड़ी स्क्रिप्ट. Next.js इन स्क्रिप्ट को क्लाइंट-साइड पर इंजेक्ट करता है. ये स्क्रिप्ट, पेज के हाइड्रेट होने के बाद चलती हैं. इसलिए, जब तक अलग से जानकारी न दी जाए, तब तक स्क्रिप्ट कॉम्पोनेंट का इस्तेमाल करके तय की गई तीसरे पक्ष की सभी स्क्रिप्ट को Next.js, डिफ़ॉल्ट रूप से बाद में लोड करता है. इससे, डिफ़ॉल्ट रूप से बेहतर परफ़ॉर्मेंस मिलती है.

  3. lazyOnload: इस विकल्प का इस्तेमाल, कम प्राथमिकता वाली स्क्रिप्ट को लेज़ी-लोड करने के लिए किया जा सकता है. ऐसा तब किया जा सकता है, जब ब्राउज़र कुछ न कर रहा हो. पेज के इंटरैक्टिव होने के तुरंत बाद, ऐसी स्क्रिप्ट से मिलने वाली सुविधाओं की ज़रूरत नहीं होती. उदाहरण के लिए, चैट या सोशल मीडिया प्लग-इन.

डेवलपर, Next.js को बता सकते हैं कि उनका ऐप्लिकेशन किसी स्क्रिप्ट का इस्तेमाल कैसे करता है. इसके लिए, उन्हें रणनीति तय करनी होगी. इससे फ़्रेमवर्क, स्क्रिप्ट को लोड करने के लिए ऑप्टिमाइज़ेशन और सबसे सही तरीके लागू कर पाता है. साथ ही, स्क्रिप्ट को लोड करने का सबसे सही क्रम पक्का कर पाता है.

स्क्रिप्ट कॉम्पोनेंट का इस्तेमाल करके, डेवलपर तीसरे पक्ष की स्क्रिप्ट को ऐप्लिकेशन में कहीं भी रख सकते हैं. इससे, तीसरे पक्ष की स्क्रिप्ट को बाद में लोड किया जा सकता है. साथ ही, ज़रूरी स्क्रिप्ट को दस्तावेज़ के लेवल पर रखा जा सकता है. इसका मतलब है कि स्क्रिप्ट कॉम्पोनेंट को, स्क्रिप्ट का इस्तेमाल करने वाले कॉम्पोनेंट के साथ रखा जा सकता है. हाइड्रेशन के बाद, स्क्रिप्ट को शुरुआती तौर पर रेंडर किए गए दस्तावेज़ के हेड में या मुख्य हिस्से के सबसे नीचे इंजेक्ट किया जाएगा. यह इस्तेमाल की गई रणनीति पर निर्भर करता है.

असर का आकलन करना

हमने Next.js कॉमर्स ऐप्लिकेशन और स्टार्टर ब्लॉग के लिए टेंप्लेट का इस्तेमाल करके, दो डेमो ऐप्लिकेशन बनाए. इनसे हमें तीसरे पक्ष की स्क्रिप्ट शामिल करने के असर को मेज़र करने में मदद मिली. Google Tag Manager और सोशल मीडिया एंबेड के लिए, आम तौर पर इस्तेमाल होने वाली विज्ञापन टेक्नोलॉजी से जुड़ी सेवा देने वाली कंपनियों को पहले सीधे तौर पर इन ऐप्लिकेशन के पेजों पर शामिल किया गया था. इसके बाद, उन्हें स्क्रिप्ट कॉम्पोनेंट के ज़रिए शामिल किया गया. इसके बाद, हमने WebPageTest पर इन पेजों की परफ़ॉर्मेंस की तुलना की.

Next.js कॉमर्स ऐप्लिकेशन में तीसरे पक्ष की स्क्रिप्ट

डेमो के लिए, कॉमर्स ऐप्लिकेशन टेंप्लेट में तीसरे पक्ष की स्क्रिप्ट जोड़ी गई थीं. इनके बारे में यहां बताया गया है.

पहले बाद में
एसिंक्रोनस के साथ Google Tag Manager दोनों स्क्रिप्ट के लिए, strategy = afterInteractive के साथ स्क्रिप्ट कॉम्पोनेंट
Twitter पर फ़ॉलो करने का बटन, जिसमें async या defer एट्रिब्यूट का इस्तेमाल नहीं किया गया है
दो स्क्रिप्ट वाले डेमो 1 के लिए, स्क्रिप्ट और स्क्रिप्ट कॉम्पोनेंट का कॉन्फ़िगरेशन.

यहां दी गई तुलना से, Next.js commerce starter-kit के दोनों वर्शन की विज़ुअल प्रोग्रेस का पता चलता है. जैसा कि देखा गया है, स्क्रिप्ट कॉम्पोनेंट को लोड करने की सही रणनीति के साथ चालू करने पर, एलसीपी करीब एक सेकंड पहले होता है.

एलसीपी में सुधार दिखाने वाली फ़िल्म स्ट्रिप की तुलना

Next.js ब्लॉग में तीसरे पक्ष की स्क्रिप्ट

डेमो ब्लॉग ऐप्लिकेशन में तीसरे पक्ष की स्क्रिप्ट जोड़ी गई थीं, जैसा कि नीचे बताया गया है.

पहले बाद में
एसिंक्रोनस के साथ Google Tag Manager चारों स्क्रिप्ट के लिए, strategy = lazyonload वाला स्क्रिप्ट कॉम्पोनेंट
Twitter पर फ़ॉलो करने का बटन, एसिंक्रोनस तरीके से लोड होने वाले स्क्रिप्ट के साथ
async या defer के बिना YouTube का 'सदस्यता लें' बटन
async या defer के बिना LinkedIn का फ़ॉलो बटन
चार स्क्रिप्ट वाले डेमो 2 के लिए, स्क्रिप्ट और स्क्रिप्ट कॉम्पोनेंट का कॉन्फ़िगरेशन.
स्क्रिप्ट कॉम्पोनेंट के साथ और उसके बिना, इंडेक्स पेज के लोड होने की प्रोग्रेस दिखाने वाला वीडियो. स्क्रिप्ट कॉम्पोनेंट की मदद से, एफ़सीपी में 0.5 सेकंड का सुधार हुआ है.

जैसा कि वीडियो में देखा जा सकता है, स्क्रिप्ट कॉम्पोनेंट के बिना पेज पर साइट का पहला एलिमेंट लोड होने में लगने वाला समय (एफ़सीपी) 0.9 सेकंड है. वहीं, स्क्रिप्ट कॉम्पोनेंट के साथ यह समय 0.4 सेकंड है.

स्क्रिप्ट कॉम्पोनेंट के लिए आगे क्या होगा

afterInteractive और lazyOnload के लिए रणनीति के विकल्प, रेंडर-ब्लॉकिंग स्क्रिप्ट पर काफ़ी कंट्रोल देते हैं. हालांकि, हम ऐसे अन्य विकल्प भी खोज रहे हैं जिनसे स्क्रिप्ट कॉम्पोनेंट की उपयोगिता बढ़ सके.

वेब वर्कर का इस्तेमाल करना

वेब वर्कर का इस्तेमाल, बैकग्राउंड थ्रेड पर इंडिपेंडेंट स्क्रिप्ट चलाने के लिए किया जा सकता है. इससे मुख्य थ्रेड को यूज़र इंटरफ़ेस के टास्क प्रोसेस करने के लिए खाली किया जा सकता है और परफ़ॉर्मेंस को बेहतर बनाया जा सकता है. वेब वर्कर, मुख्य थ्रेड से यूज़र इंटरफ़ेस (यूआई) के काम के बजाय, JavaScript प्रोसेसिंग को ऑफ़लोड करने के लिए सबसे सही होते हैं. ग्राहक सहायता या मार्केटिंग के लिए इस्तेमाल की जाने वाली स्क्रिप्ट, आम तौर पर यूज़र इंटरफ़ेस (यूआई) के साथ इंटरैक्ट नहीं करती हैं. इसलिए, इन्हें बैकग्राउंड थ्रेड पर चलाया जा सकता है. तीसरे पक्ष की एक लाइटवेट लाइब्रेरी—PartyTown—का इस्तेमाल करके, ऐसी स्क्रिप्ट को वेब वर्कर में अलग किया जा सकता है.

Next.js स्क्रिप्ट कॉम्पोनेंट के मौजूदा तरीके के साथ, हमारा सुझाव है कि इन स्क्रिप्ट को मुख्य थ्रेड पर बाद में लोड होने के लिए सेट करें. इसके लिए, रणनीति को afterInteractive या lazyOnload पर सेट करें. आने वाले समय में, हम रणनीति का एक नया विकल्प, 'worker' पेश करने का प्रस्ताव देते हैं. इससे Next.js को वेब वर्कर पर स्क्रिप्ट चलाने के लिए, PartyTown या कस्टम समाधान का इस्तेमाल करने की अनुमति मिलेगी. हम इस RFC पर डेवलपर की टिप्पणियों का स्वागत करते हैं.

सीएलएस को कम करना

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

स्क्रिप्ट कॉम्पोनेंट का इस्तेमाल, एम्बेड किए गए ऐसे एलिमेंट लोड करने के लिए किया जा सकता है जिनकी वजह से लेआउट शिफ़्ट हो सकते हैं. हम इसे बेहतर बनाने पर विचार कर रहे हैं, ताकि कॉन्फ़िगरेशन के ऐसे विकल्प उपलब्ध कराए जा सकें जिनसे सीएलएस को कम करने में मदद मिलेगी. इसे स्क्रिप्ट कॉम्पोनेंट में या कंपैनियन कॉम्पोनेंट के तौर पर उपलब्ध कराया जा सकता है.

रैपर कॉम्पोनेंट

Google Analytics या Google Tag Manager (GTM) जैसी लोकप्रिय तीसरे पक्ष की स्क्रिप्ट को शामिल करने के लिए, सिंटैक्स और लोड करने की रणनीति आम तौर पर तय होती है. इन्हें हर तरह की स्क्रिप्ट के लिए, अलग-अलग रैपर कॉम्पोनेंट में शामिल किया जा सकता है. डेवलपर को ऐप्लिकेशन के हिसाब से कुछ ही एट्रिब्यूट उपलब्ध होंगे. जैसे, ट्रैकिंग आईडी. रैपर कॉम्पोनेंट से डेवलपर को ये फ़ायदे मिलेंगे:

  1. इससे, लोकप्रिय स्क्रिप्ट टैग शामिल करना आसान हो जाता है.
  2. यह पक्का करना कि फ़्रेमवर्क, बैकग्राउंड में सबसे सही रणनीति का इस्तेमाल करे.

नतीजा

तीसरे पक्ष की स्क्रिप्ट आम तौर पर, वेबसाइट में कुछ खास सुविधाएं शामिल करने के लिए बनाई जाती हैं. हमारा सुझाव है कि कम ज़रूरी स्क्रिप्ट के असर को कम करने के लिए, उन्हें बाद में लोड होने के लिए सेट करें. Next.js स्क्रिप्ट कॉम्पोनेंट, डिफ़ॉल्ट रूप से ऐसा करता है. डेवलपर को यह भरोसा होता है कि शामिल की गई स्क्रिप्ट, ज़रूरी फ़ंक्शन में देरी नहीं करेंगी. हालांकि, ऐसा तब होगा, जब वे साफ़ तौर पर beforeInteractive रणनीति लागू न करें. Next.js स्क्रिप्ट कॉम्पोनेंट की तरह ही, फ़्रेमवर्क डेवलपर इन सुविधाओं को अन्य फ़्रेमवर्क में भी बना सकते हैं. हम Nuxt.js टीम के साथ मिलकर, ऐसा ही कॉम्पोनेंट बनाने की कोशिश कर रहे हैं. सुझावों के आधार पर, हम स्क्रिप्ट कॉम्पोनेंट को और बेहतर बनाने की उम्मीद करते हैं, ताकि अन्य इस्तेमाल के उदाहरणों को भी शामिल किया जा सके.

लोगों का आभार

इस पोस्ट पर सुझाव देने के लिए, कारा एरिकसन, जैनिक्लस राल्फ़, केटी हेम्पेनियस, फ़िलिप वॉल्टन, जेरेमी वैगनर, और ऐडी ओस्मानी को धन्यवाद.