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

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

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

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

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

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

मैं इस समस्या को कैसे ठीक करूं?

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

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

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

अगर आपको सेवा देने वाली कंपनी आपको कोई ऐसा स्निपेट देती है जिसमें document.write() शामिल है, तो आप स्क्रिप्ट एलिमेंट में async एट्रिब्यूट जोड़ सकते हैं. इसके अलावा, आप DOM API जैसे 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() अनुरोध 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 में Developer Console में सिर्फ़ एक चेतावनी दिखाकर शुरुआत की. (बीटा वर्शन जुलाई 2016 में शुरू हुआ था. हम उम्मीद करते हैं कि सितंबर 2016 में, 'स्टेबल' सभी उपयोगकर्ताओं के लिए उपलब्ध हो जाएगा.)

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

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

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

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