समस्या
क्लाइंट-साइड A/B टेस्टिंग टूल, एक स्क्रिप्ट लोड करके काम करते हैं. यह स्क्रिप्ट, ब्राउज़र के पेज बनाने की प्रोसेस शुरू करने के बाद, डीओएम में बदलाव करती है. बिना किसी रुकावट के, उपयोगकर्ता को ओरिजनल कॉन्टेंट थोड़ी देर के लिए दिखता है. इसके बाद, वह फ़्लिकर या फ़्लैश होकर एक्सपेरिमेंट के वैरिएंट पर चला जाता है. टेस्टिंग प्लैटफ़ॉर्म, पहले से ही "एंटी-फ़्लिकर स्निपेट" का इस्तेमाल करके इस समस्या को हल करते आए हैं. ये स्निपेट, opacity: 0 का इस्तेमाल करके पूरे पेज को तब तक छिपाकर रखते हैं, जब तक कि एक्सपेरिमेंट की स्क्रिप्ट पूरी नहीं हो जाती या टाइम आउट (आम तौर पर चार सेकंड) नहीं हो जाता. इस तरीके से, प्रोग्रेसिव रेंडरिंग नहीं हो पाती. साथ ही, न दिखने वाले कॉन्टेंट पर अनजाने में हुए क्लिक हो जाते हैं और बेवजह पेंट साइकल शुरू हो जाते हैं.
समस्या का हल
blocking=render एट्रिब्यूट की मदद से, <head> में मौजूद <script> या <link> एलिमेंट को रेंडर होने से रोका जा सकता है. हालांकि, पार्स होने से नहीं रोका जा सकता. ऐसा तब तक होता है, जब तक संसाधन को फ़ेच और लागू नहीं कर लिया जाता. इससे एक्सपेरिमेंट की स्क्रिप्ट को रेंडर-ब्लॉकिंग का वही व्यवहार मिलता है जो स्टाइलशीट में डिफ़ॉल्ट रूप से होता है. इससे यह पक्का होता है कि ब्राउज़र, पेज को तब तक रेंडर न करे, जब तक एक्सपेरिमेंट का वैरिएंट लागू न हो जाए. ओपैसिटी हैक, मनमाने टाइम आउट, और फ़्लिकर की समस्या नहीं होती.
लागू करने की रणनीति
- ज़रूरी: एक्सपेरिमेंटेशन स्क्रिप्ट को दस्तावेज़
<head>में डालें औरblocking="render"जोड़ें. - ज़रूरी: पक्का करें कि स्क्रिप्ट में
type="module"(इनलाइन स्क्रिप्ट के लिए बेहतर) याasync(srcवैल्यू वाली बाहरी स्क्रिप्ट के लिए बेहतर) हो. - एक्सपेरिमेंट की स्क्रिप्ट को छोटा और तेज़ रखें. स्क्रिप्ट के लागू होने तक रेंडरिंग ब्लॉक रहती है. इसलिए, बड़ी या धीमी स्क्रिप्ट की वजह से, फ़र्स्ट पेंट में देरी होती है.
- ऐसी स्क्रिप्ट पर
blocking="render"का इस्तेमाल न करें जिन्हें फ़र्स्ट पेंट से पहले चलाने की ज़रूरत नहीं है. यह सिर्फ़ उन स्क्रिप्ट के लिए है जिनका आउटपुट शुरुआती रेंडर में दिखना चाहिए. <head>के बाहर की स्क्रिप्ट परblocking="render"लागू न करें. सिर्फ़<head>में मौजूद स्क्रिप्ट, रेंडरिंग को ब्लॉक कर सकती हैं.
लागू करने के बारे में जानकारी
बुनियादी सेटअप
ज़रूरी: एक्सपेरिमेंट स्क्रिप्ट को async और blocking="render", दोनों के साथ लोड करें. async एट्रिब्यूट यह पक्का करता है कि स्क्रिप्ट, एचटीएमएल पार्सिंग को ब्लॉक न करे. इसका मतलब है कि स्क्रिप्ट फ़ेच करते समय, ब्राउज़र डीओएम बनाना जारी रखता है. blocking="render" एट्रिब्यूट यह पक्का करता है कि स्क्रिप्ट के लागू होने तक, ब्राउज़र कुछ भी रेंडर न करे.
<head>
<!--
MANDATORY: Both `async` and `blocking="render"` are required.
- `async`: Prevents parser-blocking, so the DOM is built in parallel.
- `blocking="render"`: Holds rendering until the script executes,
ensuring experiment changes are applied before the user sees anything.
-->
<script
src="https://cdn.example.com/experiment-sdk.js"
async
blocking="render"
></script>
</head>
एक्सपेरिमेंट के हिसाब से स्टाइल लोड हो रही हैं
अगर एक्सपेरिमेंट के लिए वैरिएंट स्टाइलशीट की ज़रूरत है, तो <link> एलिमेंट पर blocking="render" का इस्तेमाल करें. <head> में मौजूद स्टाइलशीट, डिफ़ॉल्ट रूप से रेंडरिंग को पहले से ही ब्लॉक करती हैं. हालांकि, डाइनैमिक तौर पर इंजेक्ट की गई स्टाइलशीट या स्क्रिप्ट के ज़रिए जोड़ी गई स्टाइलशीट ऐसा नहीं करती हैं. blocking="render" का इस्तेमाल साफ़ तौर पर तब करें, जब स्टाइलशीट को डाइनैमिक तौर पर जोड़ा गया हो या आपको अपने मकसद के बारे में साफ़ तौर पर बताना हो.
<head>
<!--
DO: Use blocking="render" on experiment stylesheets that are
dynamically inserted or conditionally loaded by the experiment SDK.
This ensures variant styles are applied before first paint.
-->
<link
rel="stylesheet"
href="https://cdn.example.com/experiment-variant-b.css"
blocking="render"
>
</head>
इनलाइन एक्सपेरिमेंट स्क्रिप्ट
अगर एक्सपेरिमेंट लॉजिक इतना छोटा है कि उसे इनलाइन किया जा सकता है, तो blocking="render" के साथ इनलाइन मॉड्यूल स्क्रिप्ट का इस्तेमाल करें. यह तब काम आता है, जब एक्सपेरिमेंट लॉजिक किसी कॉन्फ़िगरेशन को फ़ेच करता है और सीधे डीओएम में बदलाव लागू करता है.
<head>
<!--
DO: Use an inline module script when the experiment logic is small.
Module scripts are deferred by default (non-parser-blocking),
and blocking="render" ensures rendering waits for execution.
-->
<script type="module" blocking="render">
// Fetch the experiment configuration from your testing platform.
const config = await fetch('/api/experiment?id=homepage-cta')
.then(res => res.json());
// Apply the variant by setting a data attribute on <html>.
// CSS rules keyed to this attribute will style the variant.
document.documentElement.dataset.variant = config.variant;
</script>
<style>
/* Default styles (control group) */
.cta-button {
background-color: blue;
}
/* Variant B styles, activated by the data attribute */
[data-variant="b"] .cta-button {
background-color: green;
}
</style>
</head>
सबसे सही तरीके
- ज़रूरी: एक्सपेरिमेंट की स्क्रिप्ट को तेज़ी से लागू करना ज़रूरी है. धीमी स्क्रिप्ट की वजह से, रेंडरिंग में देरी होती है. रेंडर-ब्लॉकिंग स्क्रिप्ट के लिए, परफ़ॉर्मेंस बजट सेट करें. जैसे, 100 मि॰से॰ से कम समय में लागू होने वाली स्क्रिप्ट.
- ज़रूर करें: रेंडर-ब्लॉकिंग स्क्रिप्ट से, एक्सपेरिमेंट के हेवी लॉजिक को अलग करें. वैरिएंट लागू करने वाला एक छोटा, रेंडर-ब्लॉकिंग स्टब लोड करें. इसके बाद,
asyncयाdefer(blocking="render"के बिना) के साथ ज़्यादा ट्रैकिंग या Analytics स्क्रिप्ट अलग से लोड करें. - ज़रूर इस्तेमाल करें:
<html>या<body>पर डेटा एट्रिब्यूट का इस्तेमाल करें, ताकि चालू वैरिएंट का पता चल सके. साथ ही, वैरिएंट की स्टाइलिंग के लिए, उस एट्रिब्यूट से जुड़े सीएसएस सिलेक्टर का इस्तेमाल करें. इससे, रेंडर-ब्लॉकिंग स्क्रिप्ट में सीधे तौर पर डीओएम में बदलाव करने से बचा जा सकता है. - ऐनालिटिक्स, ट्रैकिंग या अन्य नॉन-विज़ुअल स्क्रिप्ट पर
blocking="render"का इस्तेमाल न करें. सिर्फ़ उन स्क्रिप्ट को रेंडरिंग ब्लॉक करनी चाहिए जो उपयोगकर्ता को पहली बार दिखने वाले कॉन्टेंट में बदलाव करती हैं. blocking="render"को लेगसी एंटी-फ़्लिकर स्निपेट के साथ न जोड़ें. दोनों एक ही समस्या को हल करते हैं. दोनों का इस्तेमाल करने से, बिना वजह देरी होती है.
फ़ॉलबैक रणनीतियां
blocking एट्रिब्यूट, सभी ब्राउज़र पर काम नहीं करता. जिन ब्राउज़र में यह एट्रिब्यूट काम नहीं करता उनमें इसे अनदेखा कर दिया जाता है. साथ ही, स्क्रिप्ट अपने डिफ़ॉल्ट ऐक्शन और सेटिंग से लोड होती है. ऊपर दिए गए उदाहरणों में, async डिफ़ॉल्ट ऐक्शन और सेटिंग है. इससे फ़्लिकर की समस्या हो सकती है. जिन ब्राउज़र पर यह सुविधा काम नहीं करती है उनमें फ़्लिकर की समस्या को रोकने के लिए, फ़ॉलबैक की ज़रूरत होती है.
फ़ॉलबैक: एंटी-फ़्लिकर स्निपेट
क्या करें: फ़ॉलबैक के तौर पर, लाइटवेट एंटी-फ़्लिकर स्निपेट का इस्तेमाल सिर्फ़ तब करें, जब blocking="render" काम न कर रहा हो. सुविधा की पहचान करने की सुविधा का इस्तेमाल करें और उन ब्राउज़र में फ़ॉलबैक को छोड़ दें जो इसे नेटिव तौर पर हैंडल करते हैं.
<head>
<!--
DO: Load the experiment script with blocking="render" for
browsers that support it. This is the preferred approach.
-->
<script
src="https://cdn.example.com/experiment-sdk.js"
async
blocking="render"
></script>
<script>
// DO: Only apply the anti-flicker fallback in browsers
// that do not support blocking="render".
if (!Object.hasOwn(HTMLScriptElement.prototype, 'blocking')) {
// Hide the page until the experiment script runs.
document.documentElement.classList.add('ab-loading');
// DO: Set a timeout to reveal the page if the experiment
// script takes too long. This prevents an indefinitely
// blank page on slow connections. Adjust the timeout
// to match your experiment SDK's expected load time.
setTimeout(() => {
document.documentElement.classList.remove('ab-loading');
}, 4000);
}
</script>
<style>
/*
DO: Use opacity to hide content during experiment loading.
This is only applied when blocking="render" is unsupported.
*/
.ab-loading {
opacity: 0 !important;
}
</style>
</head>
// DO: In your experiment SDK's initialization callback,
// remove the fallback class to reveal the page.
function onExperimentReady() {
document.documentElement.classList.remove('ab-loading');
}
ध्यान में रखने लायक अन्य बातें
- परफ़ॉर्मेंस पर असर:
blocking="render"विज़ुअल को सही तरीके से दिखाने के लिए, फ़र्स्ट-पेंट की स्पीड को कम कर देता है. सबसे बड़े एलिमेंट को रेंडर करने में लगने वाले समय (एलसीपी) और साइट का पहला एलिमेंट लोड होने में लगने वाले समय (एफ़सीपी) पर नज़र रखें. इससे यह पक्का किया जा सकेगा कि एक्सपेरिमेंट की स्क्रिप्ट की वजह से, पेज लोड होने में ज़्यादा समय न लगे. - तीसरे पक्ष की स्क्रिप्ट की विश्वसनीयता: अगर एक्सपेरिमेंट SDK टूल को तीसरे पक्ष के सीडीएन पर होस्ट किया गया है, तो सीडीएन के काम न करने पर, रेंडरिंग पूरी तरह से ब्लॉक हो सकती है. ब्राउज़र, टाइम आउट के लिए अपने अनुमान लागू करता है. ये अनुमान चार सेकंड से ज़्यादा के हो सकते हैं. हालांकि,
blocking="render"के लिए डेवलपर के कंट्रोल वाला कोई टाइम आउट नहीं होता. पक्का करें कि तीसरे पक्ष की सेवा देने वाली कंपनी, सक्रिय समय की मज़बूत गारंटी देती हो. - सर्वर-साइड विकल्प: परफ़ॉर्मेंस के लिहाज़ से अहम पेजों के लिए, क्लाइंट-साइड टेस्टिंग के बजाय सर्वर-साइड A/B टेस्टिंग का इस्तेमाल करें. इसमें सर्वर, सही वैरिएंट को सीधे रेंडर करता है. सर्वर-साइड तरीके, फ़्लिकर को पूरी तरह से खत्म कर देते हैं. इसके लिए, रेंडर-ब्लॉकिंग की कोई कीमत नहीं चुकानी पड़ती. क्लाइंट-साइड
blocking="render"का इस्तेमाल सिर्फ़ तब करें, जब सर्वर-साइड टेस्टिंग करना मुमकिन न हो.