JavaScript फ़्रेमवर्क में रिसॉर्स इनलाइनिंग

JavaScript नेटवर्क में सबसे बड़े एलिमेंट को रेंडर करने में लगने वाले समय को बेहतर बनाना.

Aurora प्रोजेक्ट के तौर पर Google, वेब के लोकप्रिय फ़्रेमवर्क के साथ काम कर रहा है, ताकि यह पक्का किया जा सके कि वे वेबसाइट की परफ़ॉर्मेंस की जानकारी के हिसाब से अच्छा परफ़ॉर्म करें. Angular और Next.js में फ़ॉन्ट इनलाइन करने की सुविधा पहले ही मिल चुकी है. इस बारे में इस लेख के पहले हिस्से में बताया गया है. दूसरा ऑप्टिमाइज़ेशन जिसमें हम कवर करेंगे वह क्रिटिकल सीएसएस इनलाइनिंग है. यह अब Angular सीएलआई में डिफ़ॉल्ट रूप से चालू है. साथ ही, इसे Nuxt.js में लागू करने पर काम जारी है.

फ़ॉन्ट इनलाइनिंग

सैकड़ों ऐप्लिकेशन का विश्लेषण करने के बाद, Aurora टीम ने पाया कि डेवलपर अक्सर index.html के <head> एलिमेंट में रेफ़रंस देकर, अपने ऐप्लिकेशन में फ़ॉन्ट शामिल करते हैं. मटीरियल आइकॉन शामिल करने पर यह कैसा दिखेगा, इसका उदाहरण यहां दिया गया है:

<!doctype html>
<html lang="en">
<head>
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  ...
</html>

इस पैटर्न के पूरी तरह से मान्य और फ़ंक्शनल होने के बावजूद, यह ऐप्लिकेशन की रेंडरिंग को ब्लॉक करता है और एक और अनुरोध करता है. समस्या को बेहतर ढंग से समझने के लिए, ऊपर एचटीएमएल में बताए गए स्टाइलशीट के सोर्स कोड पर एक नज़र डालें:

/* fallback */
@font-face {
  font-family: 'Material Icons';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/font.woff2) format('woff2');
}

.material-icons {
  /*...*/
}

ध्यान दें कि font-face परिभाषा में, fonts.gstatic.com पर होस्ट की गई किसी बाहरी फ़ाइल का रेफ़रंस कैसे दिया जाता है. ऐप्लिकेशन लोड करते समय, ब्राउज़र को पहले शीर्षक में बताई गई मूल स्टाइलशीट को डाउनलोड करना होता है.

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

इसके बाद, ब्राउज़र woff2 फ़ाइल डाउनलोड करता है. इसके बाद, ऐप्लिकेशन को रेंडर किया जा सकता है.

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

ऑप्टिमाइज़ेशन का एक मौका यह है कि बिल्ड के समय शुरुआती स्टाइलशीट को डाउनलोड किया जा सके और उसे index.html में इनलाइन किया जा सके. इससे, रनटाइम के दौरान सीडीएन में जाने की पूरी ट्रिप को स्किप कर दिया जाता है. इससे ब्लॉक करने का समय कम हो जाता है.

ऐप्लिकेशन बनाते समय, सीडीएन को एक अनुरोध भेजा जाता है, तो यह स्टाइलशीट और एचटीएमएल फ़ाइल में इसे इनलाइन करता है. साथ ही, डोमेन में <link rel=preconnect> जोड़ देता है. इस तकनीक को लागू करने पर, हमें नीचे दिया गया नतीजा मिलेगा:

<!doctype html>
<html lang="en">
<head>
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin >
  <style type="text/css">
  @font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/font.woff2) format('woff2');}.material-icons{/*...*/}</style>
  ...
</html>

फ़ॉन्ट इनलाइनिंग अब Next.js और Angular में उपलब्ध है

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

यह सुधार, Next.js v10.2 और Angular v11 में डिफ़ॉल्ट रूप से चालू है. दोनों में Google और Adobe फ़ॉन्ट को इनलाइन करने की सुविधा है. ऐसा लग रहा है कि Angular, बाद वाले वर्शन को v12.2 में उपलब्ध कराएगा.

GitHub पर Next.js में फ़ॉन्ट इनलाइनिंग को लागू करने के बारे में जानने के लिए, ऐंगुलर के बारे में इस ऑप्टिमाइज़ेशन के बारे में बताने वाला वीडियो देखें.

ज़रूरी सीएसएस को इनलाइन करना

एक और बेहतर प्रोसेस में ज़रूरी सीएसएस को इनलाइन करके, फ़र्स्ट कॉन्टेंटफ़ुल पेंट (एफ़सीपी) और सबसे बड़े कॉन्टेंटफ़ुल पेंट (एलसीपी) मेट्रिक को बेहतर बनाया जा सकता है. किसी पेज के अहम सीएसएस में, शुरुआती रेंडरिंग के दौरान इस्तेमाल की जाने वाली सभी स्टाइल शामिल होती हैं. इस विषय के बारे में ज़्यादा जानने के लिए, गैर-ज़रूरी सीएसएस को डेफ़ करना पर जाएं.

हमने देखा कि कई ऐप्लिकेशन, स्टाइल को सिंक्रोनस (एक ही समय पर) लोड कर रहे हैं. इस वजह से, ऐप्लिकेशन रेंडर होने में रुकावट आ रही है. समस्या को तुरंत ठीक करने के लिए, स्टाइल को एसिंक्रोनस रूप से लोड किया जा सकता है. media="all" की मदद से स्क्रिप्ट लोड करने के बजाय, media एट्रिब्यूट की वैल्यू को print पर सेट करें. साथ ही, लोड हो जाने पर, एट्रिब्यूट की वैल्यू को all पर सेट करें:

<link rel="stylesheet" href="..." media="print" onload="this.media='all'">

हालांकि, ऐसा करने से बिना स्टाइल वाले कॉन्टेंट में कई चीज़ें आ सकती हैं.

स्टाइल लोड होने पर, पेज फ़्लिकर दिखता है.

ऊपर दिया गया वीडियो किसी पेज की रेंडरिंग दिखाता है, जो अपनी स्टाइल को एसिंक्रोनस रूप से लोड करती है. फ़्लिकर इसलिए होता है, क्योंकि ब्राउज़र सबसे पहले स्टाइल को डाउनलोड करना शुरू करता है और फिर एचटीएमएल को रेंडर करता है. जब ब्राउज़र स्टाइल को डाउनलोड कर लेता है, तब यह लिंक एलिमेंट का onload इवेंट ट्रिगर करता है. साथ ही, media एट्रिब्यूट को all पर अपडेट करता है और स्टाइल को DOM पर लागू करता है.

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

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

आइए एक उदाहरण देखें:

यह न करें
<head>
   <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
</head>
<body>
  <section>
    <button class="primary"></button>
  </section>
</body>
/* styles.css */
section button.primary {
  /* ... */
}
.list {
  /* ... */
}

इनलाइन करने से पहले का उदाहरण.

ऊपर दिए गए उदाहरण में, क्रिटर styles.css के कॉन्टेंट को पढ़ें और पार्स करेंगे. इसके बाद, यह दो सिलेक्टर का एचटीएमएल से मिलान करता है और पता चलता है कि हम section button.primary का इस्तेमाल करते हैं. आखिर में, क्रिटर्स, पेज के <head> में मिलती-जुलती स्टाइल को इनलाइन करेंगे. इससे ये नतीजे मिलेंगे:

ऐसा करें
<head>
  <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
  <style>
  section button.primary {
    /* ... */
  }
  </style>
</head>
<body>
  <section>
    <button class="primary"></button>
  </section>
</body>

इनलाइन करने के बाद का उदाहरण.

एचटीएमएल में क्रिटिकल सीएसएस को इनलाइन करने के बाद, आपको दिखेगा कि पेज का झिलमिलाहट खत्म हो गई है:

सीएसएस इनलाइन करने के बाद लोड होने वाला पेज.

ज़रूरी सीएसएस इनलाइनिंग अब एंगुलर में उपलब्ध है और वर्शन 12 में डिफ़ॉल्ट रूप से चालू है. अगर आप v11 वर्शन का इस्तेमाल कर रहे हैं, तो इसे चालू करने के लिए angular.json में inlineCritical प्रॉपर्टी को true पर सेट करें. Next.js में इस सुविधा को ऑप्ट इन करने के लिए, experimental: { optimizeCss: true } को अपने next.config.js में जोड़ें.

मीटिंग में सामने आए नतीजे

हमने इस पोस्ट में, Chrome और वेब फ़्रेमवर्क के बीच मिलकर काम करने के बारे में बताया है. अगर आप किसी फ़्रेमवर्क के लेखक हैं और आपको पता है कि हमने आपकी टेक्नोलॉजी में जिन समस्याओं का सामना किया है, तो हमें उम्मीद है कि हमारे खोज से आपको मिलते-जुलते परफ़ॉर्मेंस ऑप्टिमाइज़ेशन को लागू करने की प्रेरणा मिलेगी.

किए गए सुधारों के बारे में ज़्यादा जानें. पेश है Aurora पोस्ट में, वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली मेट्रिक के लिए, ऑप्टिमाइज़ेशन के कामों की पूरी सूची देखी जा सकती है.