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

क्या आपको हाल ही में, Chrome के डेवलपर कंसोल में इस तरह की चेतावनी दिखी है और आपको यह जानना है कि यह क्या है?

(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>');

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

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

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

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

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

  1. उपयोगकर्ता के पास धीमा इंटरनेट कनेक्शन है. खास तौर पर, जब उपयोगकर्ता 2G इंटरनेट का इस्तेमाल कर रहा हो. (आने वाले समय में, यह बदलाव धीमे कनेक्शन वाले अन्य उपयोगकर्ताओं के लिए भी किया जा सकता है. जैसे, धीमा 3G या धीमा वाई-फ़ाई.)
  2. document.write(), टॉप लेवल के दस्तावेज़ में है. यह इंटरवेंशन, iframes में मौजूद document.written स्क्रिप्ट पर लागू नहीं होता, क्योंकि ये मुख्य पेज के रेंडर होने को ब्लॉक नहीं करते.
  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 एट्रिब्यूट जोड़ने का विकल्प हो. इसके अलावा, आपके पास document.appendChild() या parentNode.insertBefore() जैसे DOM API के साथ स्क्रिप्ट एलिमेंट जोड़ने का विकल्प भी हो सकता है.

यह पता लगाने का तरीका कि आपकी साइट पर असर पड़ा है या नहीं

कई चीज़ों से यह तय होता है कि पाबंदी लागू की गई है या नहीं. इसलिए, आपको कैसे पता चलेगा कि आप पर पाबंदी लगी है या नहीं?

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

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

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() अनुरोध, ज़रूरी शर्तों 2 से 5 को पूरा करता है (Chrome, यह चेतावनी भेजते समय कनेक्शन की ज़रूरी शर्तों को अनदेखा करता है), तो चेतावनी कुछ इस तरह दिखेगी:

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

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

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

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

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

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

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

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

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

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

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

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

क्या आपको ज़्यादा जानकारी चाहिए?

ज़्यादा जानने के लिए, ये संसाधन देखें: