लेआउट में बदलाव होने की वजह से होने वाली समस्याओं का पता लगाने और उन्हें ठीक करने के लिए, WebPageTest का इस्तेमाल करने के बारे में जानकारी.
मैंने पिछली पोस्ट में, WebPageTest में कुल लेआउट शिफ़्ट (सीएलएस) को मेज़र करने के बारे में लिखा था. सीएलएस, सभी लेआउट शिफ़्ट का एग्रीगेशन होता है. इसलिए, इस पोस्ट में मैंने सोचा कि किसी पेज पर हर लेआउट शिफ़्ट के बारे में ज़्यादा जानकारी देना और उसकी जांच करना दिलचस्प होगा. इससे यह समझने में मदद मिलेगी कि पेज में स्थिरता क्यों नहीं है. साथ ही, इससे समस्या को ठीक करने में भी मदद मिलेगी.
लेआउट शिफ़्ट मेज़र करना
लेआउट इंस्टेबिलिटी एपीआई का इस्तेमाल करके, हम किसी पेज पर होने वाले सभी लेआउट शिफ़्ट इवेंट की सूची पा सकते हैं:
new Promise(resolve => {
new PerformanceObserver(list => {
resolve(list.getEntries().filter(entry => !entry.hadRecentInput));
}).observe({type: "layout-shift", buffered: true});
}).then(console.log);
इससे लेआउट शिफ़्ट की ऐसी ऐरे बनती है जो इनपुट इवेंट से पहले नहीं होती:
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 210.78500000294298,
"duration": 0,
"value": 0.0001045969445437389,
"hadRecentInput": false,
"lastInputTime": 0
}
]
इस उदाहरण में, 210 मि॰से॰ पर सिर्फ़ 0.01% का बहुत छोटा बदलाव हुआ है.
बदलाव का समय और उसकी गंभीरता जानने से, यह पता लगाने में मदद मिलती है कि बदलाव किस वजह से हुआ. ज़्यादा टेस्टिंग करने के लिए, आइए हम लैब एनवायरमेंट के लिए WebPageTest पर वापस जाते हैं.
WebPageTest में लेआउट में हुए बदलावों को मेज़र करना
WebPageTest में सीएलएस को मेज़र करने की तरह ही, अलग-अलग लेआउट शिफ़्ट को मेज़र करने के लिए कस्टम मेट्रिक की ज़रूरत होगी. हालांकि, Chrome 77 के स्टेबल वर्शन के उपलब्ध होने के बाद, यह प्रोसेस अब आसान हो गई है. लेआउट इंस्टेबिलिटी एपीआई डिफ़ॉल्ट रूप से चालू होता है. इसलिए, Chrome 77 में किसी भी वेबसाइट पर JS स्निपेट को लागू किया जा सकता है और तुरंत नतीजे पाए जा सकते हैं. WebPageTest में, डिफ़ॉल्ट Chrome ब्राउज़र का इस्तेमाल किया जा सकता है. साथ ही, आपको कमांड लाइन फ़्लैग या Canary का इस्तेमाल करने की ज़रूरत नहीं होती.
इसलिए, WebPageTest के लिए कस्टम मेट्रिक बनाने के लिए, इस स्क्रिप्ट में बदलाव करते हैं:
[LayoutShifts]
return new Promise(resolve => {
new PerformanceObserver(list => {
resolve(JSON.stringify(list.getEntries().filter(entry => !entry.hadRecentInput)));
}).observe({type: "layout-shift", buffered: true});
});
इस स्क्रिप्ट में मौजूद प्रॉमिस, ऐरे के JSON फ़ॉर्मैट में बदल जाता है. हालांकि, यह ऐरे में नहीं बदलता. ऐसा इसलिए है, क्योंकि कस्टम मेट्रिक सिर्फ़ प्रिमिटिव डेटा टाइप जनरेट कर सकती हैं. जैसे, स्ट्रिंग या संख्याएं.
मैं जांच के लिए ismyhostfastyet.com वेबसाइट का इस्तेमाल करूंगा. मैंने इस साइट को वेब होस्ट की परफ़ॉर्मेंस की तुलना करने के लिए बनाया है.
लेआउट में बदलाव की वजहों का पता लगाना
नतीजों में, हम देख सकते हैं कि LayoutShifts कस्टम मेट्रिक की यह वैल्यू है:
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3087.2349999990547,
"duration": 0,
"value": 0.3422101449275362,
"hadRecentInput": false,
"lastInputTime": 0
}
]
संक्षेप में, 3087 मि॰से॰ पर 34.2% की एक लेआउट शिफ़्ट हुई है. समस्या की पहचान करने के लिए, WebPageTest के फ़िल्मस्ट्रिप व्यू का इस्तेमाल करें.

फ़िल्मस्ट्रिप में ~3 सेकंड के निशान तक स्क्रोल करने पर, हमें पता चलता है कि लेआउट में 34% बदलाव होने की वजह क्या है: रंगीन टेबल. वेबसाइट, JSON फ़ाइल को एसिंक्रोनस तरीके से फ़ेच करती है. इसके बाद, उसे टेबल में रेंडर करती है. टेबल शुरू में खाली होती है. इसलिए, नतीजे लोड होने पर टेबल में डेटा भरने के लिए इंतज़ार करने से लेआउट में बदलाव होता है.

बस यही नहीं. जब पेज ~4.3 सेकंड में पूरी तरह से लोड हो जाता है, तो हम देखते हैं कि पेज का <h1>
"क्या मेरा होस्टिंग प्रोवाइडर अब भी तेज़ है?" अचानक से दिखता है. ऐसा इसलिए होता है, क्योंकि साइट वेब फ़ॉन्ट का इस्तेमाल करती है और उसने रेंडरिंग को ऑप्टिमाइज़ करने के लिए कोई कदम नहीं उठाया है. ऐसा होने पर, लेआउट में कोई बदलाव नहीं दिखता. हालांकि, टाइटल पढ़ने के लिए इतना इंतज़ार करना, उपयोगकर्ता के लिए अच्छा अनुभव नहीं होता.
लेआउट में बदलाव होने की समस्या को ठीक करना
अब हमें पता चल गया है कि एसिंक्रोनस तरीके से जनरेट की गई टेबल की वजह से, व्यूपोर्ट का एक-तिहाई हिस्सा बदल रहा है. इसलिए, अब इसे ठीक करने का समय आ गया है. जब तक JSON के नतीजे लोड नहीं हो जाते, तब तक हमें टेबल के कॉन्टेंट के बारे में पता नहीं चलता. हालांकि, हम टेबल में कुछ प्लेसहोल्डर डेटा भर सकते हैं, ताकि DOM रेंडर होने पर लेआउट ज़्यादा स्थिर रहे.
प्लेसहोल्डर डेटा जनरेट करने के लिए यहां कोड दिया गया है:
function getRandomFiller(maxLength) {
var filler = '█';
var len = Math.ceil(Math.random() * maxLength);
return new Array(len).fill(filler).join('');
}
function getRandomDistribution() {
var fast = Math.random();
var avg = (1 - fast) * Math.random();
var slow = 1 - (fast + avg);
return [fast, avg, slow];
}
// Temporary placeholder data.
window.data = [];
for (var i = 0; i < 36; i++) {
var [fast, avg, slow] = getRandomDistribution();
window.data.push({
platform: getRandomFiller(10),
client: getRandomFiller(5),
n: getRandomFiller(1),
fast,
avg,
slow
});
}
updateResultsTable(sortResults(window.data, 'fast'));
प्लेसहोल्डर डेटा को क्रम से लगाने से पहले, इसे रैंडम तरीके से जनरेट किया जाता है. इसमें "█" वर्ण को कई बार दोहराया गया है, ताकि टेक्स्ट के लिए विज़ुअल प्लेसहोल्डर बनाए जा सकें. साथ ही, इसमें तीन मुख्य वैल्यू को रैंडम तरीके से जनरेट किया गया है. मैंने टेबल में कुछ स्टाइल भी जोड़ी हैं, ताकि सभी रंगों को कम किया जा सके. इससे यह साफ़ तौर पर पता चलता है कि डेटा अभी पूरी तरह से लोड नहीं हुआ है.
लेआउट स्टेबल है या नहीं, यह इस बात पर निर्भर नहीं करता कि आपने किस तरह के प्लेसहोल्डर इस्तेमाल किए हैं. प्लेसहोल्डर का मकसद, लोगों को यह भरोसा दिलाना है कि कॉन्टेंट आ रहा है और पेज काम कर रहा है.
JSON डेटा लोड होने के दौरान, प्लेसहोल्डर इस तरह दिखते हैं:

वेब फ़ॉन्ट से जुड़ी समस्या को हल करना अब बहुत आसान हो गया है. साइट Google Fonts का इस्तेमाल कर रही है. इसलिए, हमें सीएसएस अनुरोध में सिर्फ़ display=swap
प्रॉपर्टी को पास करना होगा. बस इतना ही। Fonts API, फ़ॉन्ट के एलान में font-display: swap
स्टाइल जोड़ेगा. इससे ब्राउज़र, टेक्स्ट को फ़ॉलबैक फ़ॉन्ट में तुरंत रेंडर कर पाएगा. यहां समस्या को ठीक करने के बाद, मार्कअप दिया गया है:
<link href="https://fonts.googleapis.com/css?family=Chivo:900&display=swap" rel="stylesheet">
ऑप्टिमाइज़ेशन की पुष्टि करना
WebPageTest की मदद से पेज को फिर से चलाने के बाद, हम लेआउट में होने वाले बदलावों की तुलना कर सकते हैं. इससे, बदलावों को विज़ुअलाइज़ किया जा सकता है और लेआउट में होने वाले बदलावों की नई डिग्री को मेज़र किया जा सकता है:

[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3070.9349999997357,
"duration": 0,
"value": 0.000050272187989256116,
"hadRecentInput": false,
"lastInputTime": 0
}
]
कस्टम मेट्रिक के मुताबिक, अब भी 3071 मि॰से॰ पर लेआउट शिफ़्ट हो रहा है. यह पहले के समय के आस-पास ही है. हालांकि, शिफ़्ट की गंभीरता बहुत कम है: 0.005%. मैं इसके साथ काम कर सकता/सकती हूं.
फ़िल्मस्ट्रिप से यह भी पता चलता है कि <h1>
फ़ॉन्ट तुरंत सिस्टम फ़ॉन्ट पर वापस आ जाता है. इससे उपयोगकर्ता इसे जल्द पढ़ पाते हैं.
नतीजा
इस उदाहरण की तुलना में, जटिल वेबसाइटों में लेआउट शिफ़्ट होने की समस्या ज़्यादा हो सकती है. हालांकि, इसे ठीक करने का तरीका अब भी वही है: WebPageTest में लेआउट में बदलाव की वजह से होने वाले विज़ुअल बदलाव की मेट्रिक जोड़ें. इसके बाद, नतीजों की तुलना विज़ुअल लोडिंग फ़िल्मस्ट्रिप से करें, ताकि समस्या पैदा करने वाले एलिमेंट का पता लगाया जा सके. इसके बाद, स्क्रीन के हिस्से को रिज़र्व करने के लिए प्लेसहोल्डर का इस्तेमाल करके, समस्या को ठीक करें.
(एक और बात) असल उपयोगकर्ताओं को लेआउट में होने वाली अस्थिरता का पता लगाना
किसी पेज को ऑप्टिमाइज़ करने से पहले और बाद में, WebPageTest को चलाया जा सकता है. इससे किसी मेट्रिक में हुए सुधार को देखा जा सकता है. हालांकि, सबसे ज़रूरी यह है कि उपयोगकर्ता अनुभव बेहतर हो. क्या हम साइट को बेहतर बनाने की कोशिश इसलिए नहीं कर रहे हैं?
इसलिए, यह बेहतर होगा कि हम वेब परफ़ॉर्मेंस की अपनी पारंपरिक मेट्रिक के साथ-साथ, असल उपयोगकर्ताओं के लेआउट में होने वाले बदलावों को भी मेज़र करना शुरू करें. यह ऑप्टिमाइज़ेशन के सुझावों के लिए ज़रूरी है, क्योंकि फ़ील्ड से मिले डेटा से हमें यह पता चलता है कि समस्याएं कहां हैं और हमारे सुधारों से कोई फ़र्क़ पड़ा है या नहीं.
लेआउट में होने वाले बदलाव से जुड़े अपने डेटा को इकट्ठा करने के साथ-साथ, Chrome UX Report देखें. इसमें लाखों वेबसाइटों पर, असली उपयोगकर्ताओं के अनुभव से जुड़ा कुल लेआउट शिफ़्ट डेटा शामिल होता है. इससे यह पता लगाया जा सकता है कि आपकी (या आपके प्रतिस्पर्धियों की) परफ़ॉर्मेंस कैसी है. इसके अलावा, इसका इस्तेमाल करके यह भी पता लगाया जा सकता है कि वेब पर लेआउट में बदलाव की स्थिति कैसी है.