लेआउट के अस्थिरता को ठीक करना

लेआउट के हिलने-डुलने से जुड़ी समस्याओं की पहचान करने और उन्हें ठीक करने के लिए, 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 के नतीजे लोड नहीं हो जाते, तब तक हमें टेबल के कॉन्टेंट के बारे में नहीं पता होता. हालांकि, हम टेबल में किसी तरह का प्लेसहोल्डर डेटा डाल सकते हैं, ताकि डीओएम रेंडर होने पर लेआउट अप-टू-डेट रहे.

प्लेसहोल्डर डेटा जनरेट करने का कोड यहां दिया गया है:

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 की मदद से पेज को फिर से चलाने के बाद, हम पहले और बाद की तुलना जनरेट कर सकते हैं. इससे, हमें अंतर को विज़ुअलाइज़ करने और लेआउट में होने वाले बदलावों की नई डिग्री को मेज़र करने में मदद मिलती है:

WebPageTest की फ़िल्मस्ट्रिप, जिसमें लेआउट ऑप्टिमाइज़ेशन के साथ और उसके बिना, दोनों साइटों को एक साथ लोड करते हुए दिखाया गया है.
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 रिपोर्ट देखें. इसमें लाखों वेबसाइटों पर उपयोगकर्ताओं के अनुभव से जुड़ा क्युम्युलेटिव लेआउट शिफ़्ट डेटा शामिल होता है. इसकी मदद से, यह पता लगाया जा सकता है कि आपकी (या आपके प्रतिस्पर्धियों की) परफ़ॉर्मेंस कैसी है. इसके अलावा, इसका इस्तेमाल करके यह भी पता लगाया जा सकता है कि वेब पर लेआउट की स्थिति कैसी है.