Optimize फ़र्स्ट इनपुट डिले

उपयोगकर्ता के इंटरैक्शन पर तेज़ी से प्रतिक्रिया देने का तरीका.

एडी ओस्मान
एडी उस्मान

मैंने क्लिक किया, लेकिन कुछ नहीं हुआ! मैं इस पेज से इंटरैक्ट क्यों नहीं कर सकता/सकती? 😢

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

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

अच्छे फ़िड वैल्यू 2.5 सेकंड, खराब वैल्यू 4.0 सेकंड से ज़्यादा हैं, और बीच की किसी भी स्थिति में सुधार की ज़रूरत है

लैब में एफ़आईडी का अनुमान लगाने के लिए, हमारा सुझाव है कि आप टोटल ब्लॉकिंग टाइम (टीबीटी) का इस्तेमाल करें. वे अलग-अलग चीज़ों को मेज़र करते हैं, लेकिन टीबीटी में होने वाले सुधार आम तौर पर एफ़आईडी में होने वाले सुधार के मुताबिक होते हैं.

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

ज़्यादा JavaScript एक्ज़ीक्यूशन

मुख्य थ्रेड पर JavaScript को चलाने के दौरान, ब्राउज़र ज़्यादातर उपयोगकर्ता के इनपुट का जवाब नहीं दे सकता. दूसरे शब्दों में, मुख्य थ्रेड के व्यस्त होने पर ब्राउज़र, उपयोगकर्ता के इंटरैक्शन का जवाब नहीं दे सकता. इसे बेहतर बनाने के लिए:

लंबे टास्क को ब्रेक अप करें

अगर आपने पहले ही एक पेज पर लोड होने वाले JavaScript को कम करने की कोशिश की है, तो लंबे समय तक चलने वाले कोड को छोटे और एसिंक्रोनस टास्क में बांटें.

लंबी अवधि के टास्क, JavaScript चलाने की अवधि होते हैं. इस दौरान, हो सकता है कि उपयोगकर्ताओं को आपका यूज़र इंटरफ़ेस (यूआई) काम न करे. मुख्य थ्रेड को 50 मि॰से॰ या उससे ज़्यादा समय तक ब्लॉक करने वाले कोड के किसी भी हिस्से को लॉन्ग टास्क के तौर पर दिखाया जा सकता है. लंबे टास्क, JavaScript से जुड़ी संभावित गड़बड़ियों का संकेत हैं. उपयोगकर्ता को ज़रूरत से ज़्यादा काम लोड करने और लागू करने की ज़रूरत पड़ सकती है. लंबे टास्क को छोटे-छोटे हिस्सों में बांटने से, आपकी साइट पर इनपुट में देरी कम हो सकती है.

Chrome DevTools में लंबे टास्क
Chrome DevTools, परफ़ॉर्मेंस पैनल में लंबे टास्क को विज़ुअलाइज़ करता है

एफ़आईडी को काफ़ी हद तक बेहतर होना चाहिए, क्योंकि कोड को अलग-अलग करने और लंबे टास्क को तोड़ने जैसे सबसे सही तरीके अपनाए जाते हैं. हालांकि, TBT कोई फ़ील्ड मेट्रिक नहीं है, लेकिन यह टाइम टू इंटरैक्टिव (टीटीआई) और एफ़आईडी, दोनों को बेहतर बनाने की प्रोग्रेस की जांच करने में मददगार है.

इंटरैक्शन रेडीनेस के लिए अपने पेज को ऑप्टिमाइज़ करना

JavaScript का काफ़ी इस्तेमाल करने वाले वेब ऐप्लिकेशन में, खराब एफ़आईडी और टीबीटी स्कोर की कई आम वजहें हो सकती हैं:

पहले-पक्ष की स्क्रिप्ट चलाने से, इंटरैक्शन का तैयार होने में देरी हो सकती है

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

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

पहले-पक्ष की स्क्रिप्ट को ऑप्टिमाइज़ करने के बाद, लाइटहाउस में TBT स्कोर में सुधार किए गए.

डेटा फ़ेच करने से, इंटरैक्शन रेडीनेस के कई पहलुओं पर असर पड़ सकता है

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

तीसरे पक्ष की स्क्रिप्ट चलाने से, इंटरैक्शन के इंतज़ार में भी देरी हो सकती है

  • कई साइटों में तीसरे पक्ष के टैग और आंकड़े शामिल होते हैं, जो नेटवर्क को व्यस्त रख सकते हैं. साथ ही, मुख्य थ्रेड को समय-समय पर काम नहीं करता, जिससे इंटरैक्शन के इंतज़ार में लगने वाला समय प्रभावित होता है. तीसरे पक्ष के कोड को मांग पर लोड करने के बारे में जानें. उदाहरण के लिए, पेज के नीचे वाले विज्ञापनों को तब तक लोड न करें, जब तक कि उन्हें व्यूपोर्ट के पास स्क्रोल न किया जाए.
  • कुछ मामलों में तीसरे पक्ष की स्क्रिप्ट, मुख्य थ्रेड पर प्राथमिकता और बैंडविड्थ के आधार पर पहले पक्ष की स्क्रिप्ट को पहले से ही रोक सकती हैं. इससे, पेज के इंटरैक्शन के लिए तैयार होने में लगने वाले समय में भी देरी होती है. जिन चीज़ों को आपके हिसाब से उपयोगकर्ताओं के लिए सबसे ज़्यादा काम का माना जाता है उन्हें लोड करने की प्राथमिकता तय करें.

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

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

अपनी साइट पर वेब वर्कर के इस्तेमाल को आसान बनाने के लिए, इन लाइब्रेरी का इस्तेमाल करें:

  • Comlink: यह एक हेल्पर लाइब्रेरी है, जो postMessage को एब्स्ट्रैक्ट करती है और इस्तेमाल करना आसान बनाती है
  • वर्कवे: सामान्य कामों के लिए इस्तेमाल किया जाने वाला वेब वर्कर एक्सपोर्टर
  • वर्कराइज़: मॉड्यूल को किसी वेब वर्कर में ले जाएं

JavaScript चलाने का समय कम करें

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

अपने पेज पर JavaScript चलाए जाने की संख्या कम करने के लिए:

  • इस्तेमाल नहीं की गई JavaScript को रोकें
  • इस्तेमाल न किए गए पॉलीफ़िल को कम करें

इस्तेमाल नहीं की गई JavaScript को रोकें

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

Chrome DevTools में कवरेज टैब से, आपको यह पता चल सकता है कि आपके वेब पेज पर JavaScript का कितना इस्तेमाल नहीं किया जा रहा है.

कवरेज टैब.

इस्तेमाल न किए गए JavaScript को कम करने के लिए:

  • कोड को कई हिस्सों में बांटें
  • async या defer का इस्तेमाल करके, तीसरे पक्ष की स्क्रिप्ट के साथ-साथ, गैर-ज़रूरी JavaScript को रोकें

कोड-स्प्लिटिंग एक बड़े JavaScript बंडल को छोटे-छोटे हिस्सों में बांटने का सिद्धांत है. इसे किसी शर्त के साथ लोड किया जा सकता है (इसे लेज़ी लोडिंग भी कहा जाता है). ज़्यादातर नए ब्राउज़र में डाइनैमिक इंपोर्ट सिंटैक्स का इस्तेमाल किया जा सकता है. इससे, मांग पर मॉड्यूल फ़ेच किया जा सकता है:

import('module.js').then((module) => {
  // Do something with the module.
});

उपयोगकर्ता के कुछ इंटरैक्शन (जैसे कि रूट बदलना या मोडल दिखाना) पर JavaScript को डाइनैमिक तरीके से इंपोर्ट करने से, यह पक्का हो जाएगा कि शुरुआती पेज लोड के लिए इस्तेमाल नहीं किया गया कोड सिर्फ़ ज़रूरत पड़ने पर फ़ेच किया जाए.

सामान्य ब्राउज़र सहायता के अलावा, कई अलग-अलग बिल्ड सिस्टम में डाइनैमिक इंपोर्ट सिंटैक्स का इस्तेमाल किया जा सकता है.

  • अगर मॉड्यूल बंडलर के तौर पर webpack, Rollup या Parcel का इस्तेमाल किया जाता है, तो इनकी डाइनैमिक इंपोर्ट सुविधा का फ़ायदा उठाएं.
  • React, Angular, और Vue जैसे क्लाइंट-साइड फ़्रेमवर्क, कॉम्पोनेंट-लेवल पर लेज़ी-लोडिंग को आसान बनाने के लिए ऐब्सट्रैक्ट कार्रवाई उपलब्ध कराते हैं.

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

<script defer src="…"></script>
<script async src="…"></script>

जब तक कोई खास वजह न बताई गई हो, तब तक तीसरे पक्ष की सभी स्क्रिप्ट को, डिफ़ॉल्ट रूप से defer या async के साथ लोड किया जाना चाहिए.

इस्तेमाल न किए गए पॉलीफ़िल को कम करें

अगर आपने मॉडर्न JavaScript सिंटैक्स का इस्तेमाल करके कोड लिखा है और मॉडर्न ब्राउज़र एपीआई का इस्तेमाल किया है, तो आपको इसे ट्रांसपाइल करना होगा और पॉलीफ़िल को शामिल करना होगा, ताकि यह पुराने ब्राउज़र में काम कर सके.

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

अपनी साइट पर पॉलीफ़िल के इस्तेमाल को ऑप्टिमाइज़ करने के लिए:

  • अगर Babel को ट्रांसपाइलर के तौर पर इस्तेमाल किया जाता है, तो @babel/preset-env का इस्तेमाल सिर्फ़ उन ब्राउज़र के लिए ज़रूरी पॉलीफ़िल को शामिल करने के लिए करें जिन्हें टारगेट करना है. बेबल 7.9 के लिए, किसी भी ग़ैर-ज़रूरी पॉलीफ़िल को कम करने के लिए, bugfixes विकल्प को चालू करें
  • दो अलग-अलग बंडल डिलीवर करने के लिए, मॉड्यूल/नोमॉड्यूल पैटर्न का इस्तेमाल करें (@babel/preset-env, target.esmodules के ज़रिए भी इसके साथ काम करता है)

    <script type="module" src="modern.js"></script>
    <script nomodule src="legacy.js" defer></script>
    

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

डेवलपर टूल

एफ़आईडी को मेज़र और डीबग करने के लिए, कई टूल उपलब्ध हैं:

  • Lighthouse 6.0 में एफ़आईडी के लिए सहायता शामिल नहीं होती, क्योंकि यह एक फ़ील्ड मेट्रिक है. हालांकि, टोटल ब्लॉकिंग टाइम (टीबीटी) का इस्तेमाल प्रॉक्सी के तौर पर किया जा सकता है. TBT को बेहतर बनाने वाले ऑप्टिमाइज़ेशन से फ़ील्ड में भी एफ़आईडी को बेहतर बनाया जा सकता है.

    लाइटहाउस 6.0.

  • Chrome उपयोगकर्ता अनुभव रिपोर्ट में ऑरिजिन लेवल पर इकट्ठा की गई असल दुनिया की एफ़आईडी वैल्यू मिलती हैं

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