document.write() के साथ दखल देना

पॉल किनलन
पॉल किनलन

क्या आपको हाल ही में, Chrome में अपने Developer Console में नीचे दी गई चेतावनी के बारे में जानकारी मिली है और आपने सोचा है कि वह क्या थी?

(index):34 A Parser-blocking, cross-origin script,
https://paul.kinlan.me/ad-inject.js, is invoked via document.write().
This may be blocked by the browser if the device has poor network connectivity.

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

खराब परफ़ॉर्मेंस की एक वजह यह है कि पेजों में document.write() का इस्तेमाल किया जाता है. खास तौर पर, ऐसे पेज जिनमें स्क्रिप्ट इंजेक्ट करने वाले पेज का इस्तेमाल किया जाता है. नीचे दिया गया तरीका जितना कारगर नहीं है, इसमें उपयोगकर्ताओं को असल समस्याएं आ सकती हैं.

document.write('<script src="https://example.com/ad-inject.js"></script>');

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

2G जैसे धीमा इंटरनेट कनेक्शन इस्तेमाल करने वाले लोगों को, document.write() के ज़रिए डाइनैमिक तरीके से इंजेक्ट की गई बाहरी स्क्रिप्ट की वजह से, मुख्य पेज का कॉन्टेंट दिखने में 10 सेकंड तक देरी हो सकती है. इसकी वजह से, पेज या तो लोड नहीं हो पाते हैं या इतना ज़्यादा समय लग जाता है कि उपयोगकर्ता बस अपना काम छोड़ देता है. Chrome में इंस्ट्रूमेंटेशन के आधार पर, हमें पता चला है कि document.write() के ज़रिए शामिल की गई तीसरे पक्ष की स्क्रिप्ट वाले पेजों की लोडिंग, 2G पर दूसरे पेजों की तुलना में आम तौर पर दोगुनी होती है.

हमने 28 दिनों के फ़ील्ड ट्रायल से डेटा इकट्ठा किया. यह डेटा, Chrome के स्थिर 1% उपयोगकर्ताओं पर इकट्ठा किया गया था, जो सिर्फ़ 2G कनेक्शन इस्तेमाल करने वाले उपयोगकर्ताओं के लिए था. हमने देखा कि 2G पर लोड होने वाले सभी पेज में से 7.6% में, पार्सर को ब्लॉक करने वाली कम से कम एक क्रॉस-साइट स्क्रिप्ट शामिल है. इसे टॉप लेवल के दस्तावेज़ में document.write() के ज़रिए शामिल किया गया था. इन स्क्रिप्ट के लोड को ब्लॉक करने की वजह से, हमें लोड होने से जुड़े ये सुधार दिखे:

  • फ़र्स्ट कॉन्टेंटफ़ुल पेंट पर 10% ज़्यादा पेज लोड होते हैं (इससे उपयोगकर्ता को यह पुष्टि मिलती है कि पेज सही तरीके से लोड हो रहा है), 25% ज़्यादा पेज लोड होते हैं, जो पूरी तरह से पार्स की गई स्थिति में पहुंच जाते हैं. साथ ही, पेज के फिर से लोड होने में 10% की कमी आती है, जिससे उपयोगकर्ता को कम परेशानी होती है.
  • फ़र्स्ट कॉन्टेंटफ़ुल पेंट मिलने तक, मीन टाइम में 21% की कमी (एक सेकंड से ज़्यादा तेज़)
  • किसी पेज को पार्स करने में लगने वाले औसत समय में 38% की कमी, जो करीब छह सेकंड के सुधार को दिखाती है. इससे उपयोगकर्ता को ज़रूरी जानकारी दिखाने में लगने वाला समय काफ़ी कम हो जाता है.

इस डेटा को ध्यान में रखते हुए, वर्शन 55 से शुरू होने वाला Chrome, जब हम Chrome में document.write() को हैंडल करने के तरीके में बदलाव करके इस अनजान-खराब पैटर्न का पता लगाते हैं, तो वह सभी उपयोगकर्ताओं की ओर से इंटरैक्ट करता है (Chrome की स्थिति देखें). खास तौर पर, नीचे दी गई सभी शर्तें पूरी होने पर, Chrome document.write() के ज़रिए इंजेक्ट किए गए <script> एलिमेंट को एक्ज़ीक्यूट नहीं करेगा:

  1. जब उपयोगकर्ता 2G का इस्तेमाल कर रहा/रही है, तब वह धीमा इंटरनेट कनेक्शन इस्तेमाल कर रहा है. (आने वाले समय में, इस बदलाव को दूसरे उपयोगकर्ताओं के लिए भी लागू किया जा सकता है जिनके इंटरनेट कनेक्शन की रफ़्तार धीमी है. उदाहरण के लिए, धीमा 3G या धीमा वाई-फ़ाई.)
  2. document.write(), टॉप लेवल के दस्तावेज़ में है. यह इंटरवेंशन, iframes में मौजूद document.write की स्क्रिप्ट पर लागू नहीं होता, क्योंकि ये मुख्य पेज को रेंडर होने से नहीं रोकते हैं.
  3. document.write() में स्क्रिप्ट पार्सर ब्लॉक कर रही है. 'async' या 'defer' एट्रिब्यूट वाली स्क्रिप्ट अब भी काम करेंगी.
  4. स्क्रिप्ट एक ही साइट पर होस्ट नहीं की गई है. दूसरे शब्दों में, Chrome से मेल खाने वाले eTLD+1 वाली स्क्रिप्ट (उदाहरण के लिए, www.example.org पर js.example.org पर होस्ट की गई स्क्रिप्ट) में दखल नहीं देगा.
  5. स्क्रिप्ट पहले से ही ब्राउज़र के एचटीटीपी कैश में मौजूद नहीं है. कैश मेमोरी में मौजूद स्क्रिप्ट को प्रोसेस करने में नेटवर्क से कोई देरी नहीं होगी और वे तब भी काम करती रहेंगी.
  6. पेज के लिए किया गया अनुरोध, फिर से लोड करने का अनुरोध नहीं होता. अगर उपयोगकर्ता, पेज को फिर से लोड करता है, तो Chrome बीच में रुकावट नहीं डालेगा और पेज को पहले की तरह काम करेगा.

तीसरे पक्ष के स्निपेट, स्क्रिप्ट लोड करने के लिए कभी-कभी document.write() का इस्तेमाल करते हैं. अच्छी बात यह है कि ज़्यादातर तीसरे पक्ष एसिंक्रोनस लोडिंग के विकल्प उपलब्ध कराते हैं. इस वजह से तीसरे पक्ष की स्क्रिप्ट, पेज पर बाकी कॉन्टेंट दिखाए जाने से रोके बिना लोड हो जाती हैं.

मैं इसे कैसे ठीक करूं?

इस आसान जवाब में, document.write() का इस्तेमाल करके स्क्रिप्ट इंजेक्ट नहीं की जानी चाहिए. हमारे पास एसिंक्रोनस लोडर सहायता के लिए जानी-पहचानी सेवाओं का एक सेट है, जिन्हें हम आपको जांचते रहने का सुझाव देते हैं.

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

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

अगर सेवा देने वाली कंपनी आपको ऐसा स्निपेट देता है जिसमें document.write() शामिल है, तो आपके लिए स्क्रिप्ट एलिमेंट में async एट्रिब्यूट जोड़ा जा सकता है. इसके अलावा, आपके पास स्क्रिप्ट एलिमेंट को DOM एपीआई जैसे document.appendChild() या parentNode.insertBefore() के साथ जोड़ने की भी संभावना है.

कैसे पता लगाएं कि आपकी साइट कब प्रभावित हुई

ऐसे कई शर्तें हैं जिनसे यह तय होता है कि पाबंदी लगाई गई है या नहीं. ऐसे में आपको कैसे पता चलेगा कि आपके खाते पर पाबंदी लगाई गई है?

यह पता लगाना कि उपयोगकर्ता 2G का इस्तेमाल कर रहा है या नहीं

इस बदलाव के संभावित असर को समझने के लिए, आपको सबसे पहले यह समझना होगा कि आपके कितने उपयोगकर्ता 2G का इस्तेमाल करेंगे. Chrome में उपलब्ध Network Information API का इस्तेमाल करके, उपयोगकर्ता के मौजूदा नेटवर्क टाइप और स्पीड का पता लगाया जा सकता है. इसके बाद, ऐनलिटिक या रीयल यूज़र मेट्रिक (आरयूएम) सिस्टम को चेतावनी भेजी जा सकती है.

if(navigator.connection &&
    navigator.connection.type === 'cellular' &&
    navigator.connection.downlinkMax <= 0.115) {
    // Notify your service to indicate that you might be affected by this restriction.
}

Chrome DevTools में चेतावनियां देखना

Chrome 53 के बाद से, DevTools समस्या वाले document.write() स्टेटमेंट के लिए चेतावनियां जारी करता है. खास तौर पर, अगर कोई document.write() अनुरोध दो से पांच तक की शर्तों को पूरा करता है (इस चेतावनी को भेजते समय, Chrome कनेक्शन से जुड़ी ज़रूरी शर्तों को अनदेखा करता है), तो चेतावनी कुछ इस तरह दिखेगी:

दस्तावेज़ लिखने से जुड़ी चेतावनी.

Chrome DevTools में चेतावनियां देखना बढ़िया है, लेकिन बड़े पैमाने पर इसका पता कैसे लगाया जाता है? इंटरवेंशन होने पर, आपके सर्वर पर भेजे गए एचटीटीपी हेडर की जांच की जा सकती है.

स्क्रिप्ट संसाधन पर अपने एचटीटीपी हेडर की जांच करें

जब document.write से डाली गई किसी स्क्रिप्ट को ब्लॉक किया जाता है, तो Chrome नीचे दिए गए हेडर को अनुरोध किए गए संसाधन पर भेजेगा:

Intervention: <https://shorturl/relevant/spec>;

जब document.write से डाली गई कोई स्क्रिप्ट मिलती है और उसे अलग-अलग स्थितियों में ब्लॉक किया जा सकता है, तो Chrome यह जानकारी भेज सकता है:

Intervention: <https://shorturl/relevant/spec>; level="warning"

इंटरवेंशन हेडर, स्क्रिप्ट के लिए GET अनुरोध के हिस्से के तौर पर भेजा जाएगा. (असल इंटरवेंशन की स्थिति में, इसे एसिंक्रोनस रूप से) भेजा जाएगा.

भविष्य में क्या है?

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

हम Chrome 54 से 2G उपयोगकर्ताओं के लिए, इंजेक्ट की गई स्क्रिप्ट को फ़िलहाल ब्लॉक करेंगे. ऐसा अनुमान है कि अक्टूबर 2016 के मध्य तक, यह सभी उपयोगकर्ताओं के लिए ठीक से काम करने वाली स्क्रिप्ट में होगा. ज़्यादा अपडेट के लिए Chrome की स्थिति से जुड़ी एंट्री देखें.

समय के साथ, हम जब भी किसी उपयोगकर्ता के पास धीमा कनेक्शन (जैसे कि धीमा 3G या वाई-फ़ाई) होता है, तो हम हस्तक्षेप करते हैं. Chrome की स्थिति की जानकारी को फ़ॉलो करें.

क्या आपको ज़्यादा जानना है?

ज़्यादा जानकारी के लिए, यहां दिए गए अन्य संसाधन देखें: