ऐंगुलर इमेज डायरेक्टिव के साथ इमेज ऑप्टिमाइज़ करना

Kara Erickson
Kara Erickson
Leena Sohoni
Leena Sohoni

मई 2022 में, Aurora और Angular टीमों ने एलान किया था कि वे Angular के लिए इमेज डायरेक्टिव पर साथ मिलकर काम करेंगी. निर्देश को हाल ही में, Angular v14.2 के हिस्से के तौर पर डेवलपर की झलक के लिए रिलीज़ किया गया था. इस पोस्ट में बताया गया है कि नया इमेज डायरेक्टिव, NgOptimizedImage, Angular में इमेज ऑप्टिमाइज़ेशन के साथ कैसे काम करता है.

बैकग्राउंड

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

इमेज की संख्या और साइज़ बढ़ने की वजह से, वेब पेजों की परफ़ॉर्मेंस पर असर पड़ सकता है. साथ ही, वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी वाली मेट्रिक पर भी असर पड़ सकता है. साल 2021 में, 79.4% डेस्कटॉप पेजों में इस्तेमाल की गई इमेज, सबसे बड़े एलिमेंट को रेंडर करने में लगने वाले समय (LCP) का हिस्सा थी. इसलिए, ऑप्टिमाइज़ की गई इमेज की खोज, हम में से कई लोगों के लिए लगातार कोशिश हो रही है.

Aurora टीम का मानना है कि यह फ़्रेमवर्क की मदद से डेवलपर की आम चुनौतियों का सामना करने में मदद करता है. इमेज ऑप्टिमाइज़ेशन स्पेस में उन्होंने सबसे पहले Next.js इमेज कॉम्पोनेंट शामिल किया था. उन्होंने इस कॉम्पोनेंट को टेस्ट किया. इससे यह पता चलता है कि इमेज ऑप्टिमाइज़ेशन के डेवलपर अनुभव (DX) को बेहतर बनाने से, फ़्रेमवर्क का इस्तेमाल करने वाले ज़्यादा ऐप्लिकेशन की परफ़ॉर्मेंस बेहतर हो सकती है या नहीं.

Next.js के उपयोगकर्ता Leboncoin से मिले नतीजे का पहला सेट उत्साह बढ़ाने वाला था. next/image का इस्तेमाल शुरू करने के बाद, Leboncoin ने एलसीपी में काफ़ी सुधार देखा (2.4 से 1.7 सेकंड तक). कम्यूनिटी में next/image के बाद के बाद, Next.js ऑरिजिन के इस्तेमाल की वजह से एलसीपी थ्रेशोल्ड को पूरा करने में मदद मिली. जल्द ही, दूसरे फ़्रेमवर्क में इससे मिलती-जुलती सुविधाओं के लिए अनुरोध मिलने लगे. इनमें से एक फ़्रेमवर्क, Angular है.

इस वजह से, Aurora ने इन फ़्रेमवर्क के लिए इमेज के कॉम्पोनेंट का प्रोटोटाइप तैयार करने के लिए Angular और Nuxt के साथ सलाह ली. Nuxt इमेज कॉम्पोनेंट पिछले साल रिलीज़ किया गया था. अब Angular इमेज डायरेक्टिव (NgOptimizedImage) को रिलीज़ कर दिया गया है, ताकि इमेज ऑप्टिमाइज़ेशन डिफ़ॉल्ट को Angular पर लाया जा सके.

अवसर

Angular आज के डेवलपर के इस्तेमाल किए जाने वाले सबसे बड़े JavaScript फ़्रेमवर्क में से एक है. इसका इस्तेमाल 50 हज़ार से ज़्यादा ऑरिजिन को मोबाइल पर HTTPArchive के ज़रिए क्रॉल किया जाता है. साथ ही, यह एनपीएम पर हर हफ़्ते करीब 30 लाख डाउनलोड करता है.

पिछले एक साल में Angular वेबसाइटों के लिए एलसीपी.

वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली रिपोर्ट से पता चलता है कि उन ऐंग्युलर ऑरिजिन का प्रतिशत जिन्होंने "अच्छा" रेटिंग दी है एलसीपी थ्रेशोल्ड पर अब भी काम करने की ज़रूरत है. जून 2022 में, सिर्फ़ 18.74% Angular साइटों को मोबाइल पर अच्छा एलसीपी मिला. मोबाइल और डेस्कटॉप पर, इमेज 70% से ज़्यादा वेब पेजों के लिए एलसीपी एलिमेंट होती हैं. इसलिए, ऐंग्युलर वेबसाइटों पर एलसीपी के खराब होने की एक मुख्य वजह, इमेज के लिए ऑप्टिमाइज़ न की गई एलसीपी इमेज हो सकती हैं.

Angular इमेज डायरेक्टिव को, इन संख्याओं को बेहतर बनाने के लिए बनाया गया था.

NgOptimizedImage डायरेक्टिव के लिए MVP

Angular इमेज डायरेक्टिव का MVP, उन इमेज कॉम्पोनेंट के लेसन पर आधारित है जो Aurora ने अब तक बनाए हैं. साथ ही, यह भी Angular के क्लाइंट-साइड रेंडरिंग अनुभव के हिसाब से डिज़ाइन किया गया है. मानक इमेज ऑप्टिमाइज़ेशन से जुड़ी कई समस्याओं को इनमें से किसी ने हल किया है:

  • मज़बूत डिफ़ॉल्ट सेटिंग जोड़ी जा रही हैं.
  • सबसे सही तरीकों का पालन करने के लिए, गड़बड़ियां या चेतावनियां दी गई हों.

डिज़ाइन की खास बातें यहां दी गई हैं:

  1. इंटेलिजेंट लेज़ी लोडिंग

    आम तौर पर, ऐसी इमेज लेज़ी लोड होनी चाहिए जो उपयोगकर्ता को पेज लोड होने पर नहीं दिखती हैं. उदाहरण के लिए, वेबसाइट में फ़ोल्ड के नीचे दिखने वाली इमेज या छिपी हुई कैरसेल इमेज. लेज़ी लोडिंग से ब्राउज़र के रिसॉर्स को, ज़रूरी टेक्स्ट, मीडिया या स्क्रिप्ट लोड करने में मदद मिलती है. ज़्यादातर इमेज अहम नहीं हैं और उन्हें लेज़ी लोड होना चाहिए. हालांकि, 2021 में सिर्फ़ 7.8% पेजों ने नेटिव लेज़ी लोडिंग का इस्तेमाल किया.

    Angular इमेज डायरेक्टिव के हिसाब से, लेज़ी डिफ़ॉल्ट रूप से ऐसी इमेज लोड करता है जो ज़रूरी नहीं हैं. साथ ही, सिर्फ़ उन इमेज को लोड करता है जिन पर खास तौर पर priority का निशान लगाया गया है. इससे यह पक्का किया जाता है कि ज़्यादातर इमेज, सबसे सही तरीके से लोड हों.

  2. गंभीर इमेज को प्राथमिकता देना

    संसाधन के संकेत जोड़ना (उदाहरण के लिए, preload या preconnect), अहम इमेज लोड होने को प्राथमिकता देने के लिए, सुझाया गया सबसे सही तरीका है. हालांकि, ज़्यादातर ऐप्लिकेशन इनका इस्तेमाल नहीं कर रहे हैं. साल 2021 के वेब कैलेंडर के मुताबिक, सिर्फ़ 12.7% मोबाइल पेजों पर पहले से कनेक्ट करने के संकेतों का इस्तेमाल किया जाता है. वहीं, सिर्फ़ 22.1% मोबाइल पेजों पर, पहले से लोड करने के संकेतों का इस्तेमाल किया जाता है.

    जब इमेज को प्राथमिकता के तौर पर मार्क किया जाता है, तब इमेज डायरेक्टिव दो हिस्सों में काम करता है.

    • यह इमेज की फ़ेच प्राथमिकता को "high" पर सेट करता है, ताकि ब्राउज़र यह जान सके कि इसे इमेज को ज़्यादा प्राथमिकता से डाउनलोड करना चाहिए.
    • डेवलपमेंट मोड में, रनटाइम की जांच से इस बात की पुष्टि होती है कि इमेज के ऑरिजिन के हिसाब से preconnect संसाधन संकेत को शामिल किया गया है.

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

    ऑटोमेशन और कंफ़ॉर्मैंस के कॉम्बिनेशन से यह पक्का होता है कि एलसीपी इमेज में preconnect संकेत है, fetchpriority एट्रिब्यूट की वैल्यू high है, और यह लेज़ी लोड नहीं होगी.

  3. लोकप्रिय इमेज टूल के लिए ऑप्टिमाइज़ किया गया कॉन्फ़िगरेशन

    हमारा सुझाव है कि Angular ऐप्लिकेशन इमेज सीडीएन का इस्तेमाल करें. ये अक्सर डिफ़ॉल्ट रूप से ऑप्टिमाइज़ेशन सेवाएं देते हैं.

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

    // in module providers:
    provideImgixLoader('https://mysite.net/assets/')
    
    // in markup
    <img ngSrc="image.png" >
    <img ngSrc="image2.png" >
    

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

    <img src="https://mysite.net/assets/image.png">
    <img src="https://mysite.net/assets/image2.png">
    

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

  4. पहले से मौजूद गड़बड़ियां और चेतावनियां

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

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

    2. आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात): इमेज डायरेक्टिव के तौर पर, इमेज डायरेक्टिव के तौर पर एक गड़बड़ी मिलती है, ताकि डेवलपर को यह पता चल सके कि एचटीएमएल में तय किए गए width:height का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) रेंडर की गई इमेज के असल आसपेक्ट रेशियो के आस-पास नहीं है. इस वजह से, स्क्रीन पर इमेज खराब दिख सकती है. ऐसा तब हो सकता है, जब

      1. आपने गलती से गलत डाइमेंशन (चौड़ाई या ऊंचाई) तय कर दिया हो या
      2. अगर आपने अपनी सीएसएस में एक डाइमेंशन को प्रतिशत के हिसाब से तय किया है, लेकिन दूसरा नहीं. उदाहरण के लिए, width: 100% को height: auto की ज़रूरत है, ताकि इमेज के दोनों डाइमेंशन में बढ़ोतरी हो.
    3. बड़े साइज़ की इमेज: अगर इमेज, srcset के बारे में नहीं बताती है और रेंडर की गई इमेज से काफ़ी बड़ी है, तो डायरेक्टिव एक चेतावनी दिखाएगा, जिसमें srcset और sizes एट्रिब्यूट के इस्तेमाल का सुझाव दिया जाएगा.

    4. इमेज की सघनता: अगर आप ऐसी इमेज को srcset में शामिल करने की कोशिश करते हैं जिसकी पिक्सल सघनता 3x से ज़्यादा हो, तो निर्देश वाला गड़बड़ी का मैसेज दिखाएगा. आम तौर पर, ब्यौरे में 2x से ज़्यादा वैल्यू का इस्तेमाल करने का सुझाव नहीं दिया जाता. ऐसा इसलिए, क्योंकि इसकी वजह से हाई रिज़ॉल्यूशन वाले मोबाइल डिवाइसों को बड़ी इमेज डाउनलोड करने में मदद मिलती है. इतना ही नहीं, मानवीय आंख दो गुना से ज़्यादा का अंतर नहीं बता सकती.

चुनौतियां

NgOptimizedImage को डिज़ाइन करते समय, इमेज ऑप्टिमाइज़ेशन की रणनीतियों को क्लाइंट-साइड फ़्रेमवर्क के तहत इस्तेमाल करना सबसे बड़ी चुनौती थी. Next.js पर रेंडरिंग का डिफ़ॉल्ट अनुभव सर्वर साइड रेंडरिंग (एसएसआर) या स्टैटिक साइट जनरेशन (एसएसजी) है, जबकि ऐंग्युलर पर क्लाइंट साइड रेंडरिंग (सीएसआर) है. हालांकि, Angular एक एसएसआर लाइब्रेरी के साथ काम करता है, जो कोणीय/यूनिवर्सल के तौर पर काम करती है. हालांकि, ज़्यादातर Angular ऐप्लिकेशन (~60%) में सीएसआर का इस्तेमाल किया जाता है.

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

सामने आने वाली कुछ चुनौतियां इस तरह हैं:

  1. सहायता के लिए, संसाधन से जुड़े संकेत

    ज़रूरी ऐसेट को पहले से लोड करने से, ब्राउज़र को उन्हें जल्दी खोजने में मदद मिलती है. हालांकि, Angular ऐप्लिकेशन में संसाधन के संकेत शामिल करना मुश्किल है, क्योंकि:

    मैन्युअल तरीके से जोड़ना: डेवलपर के लिए, preload संसाधन संकेत को मैन्युअल तौर पर जोड़ना मुश्किल होता है. Angular, पूरे प्रोजेक्ट या वेबसाइट के सभी रूट के लिए, शेयर की गई एक index.html फ़ाइल का इस्तेमाल करता है. इसलिए, दस्तावेज़ का <head> हर रास्ते के लिए एक जैसा है (कम से कम हर रूट पर). <head> में preload संकेत जोड़ने का मतलब यह होगा कि संसाधन को सभी रास्तों के लिए पहले से लोड कर दिया जाएगा, भले ही इसकी ज़रूरत न हो. इसलिए, preload संकेत को मैन्युअल तौर पर जोड़ने का सुझाव नहीं दिया जाता.

    रेंडर के दौरान अपने-आप जुड़ना: सीएसआर ऐप्लिकेशन में रेंडर होने के दौरान, दस्तावेज़ में सबसे ऊपर प्रीलोड संकेत जोड़ने के लिए फ़्रेमवर्क का इस्तेमाल करने से मदद नहीं मिलती. JavaScript के डाउनलोड और लागू होने के बाद रेंडरिंग होती है. इसलिए, <head> को रेंडर होने में बहुत देर होगी, क्योंकि इसकी कोई वैल्यू नहीं होगी.

    डायरेक्टिव के पहले वर्शन में, इमेज को प्राथमिकता देने के लिए preload के बजाय preconnect संकेत और fetchpriority संकेतों का कॉम्बिनेशन इस्तेमाल किया जाता है. हालांकि, Aurora फ़िलहाल Angular CLI टीम के साथ काम कर रहा है, ताकि बिल्ड के समय तैयार करते समय संसाधनों के संकेत अपने-आप दिए जाने की सुविधा चालू की जा सके. हमारे साथ बने रहें!

  2. सर्वर पर इमेज के साइज़ और फ़ॉर्मैट को ऑप्टिमाइज़ करना

    आम तौर पर, Angular ऐप्लिकेशन क्लाइंट-साइड पर रेंडर होते हैं. इसलिए, अनुरोध के समय फ़ाइल सिस्टम में मौजूद इमेज को कंप्रेस नहीं किया जा सकता. उन्हें बिना किसी बदलाव के दिखाया जाता है. इस वजह से, इमेज सीडीएन इस्तेमाल करने का सुझाव दिया जाता है कि इमेज को कंप्रेस करके, ज़रूरत के हिसाब से WebP या AVIF जैसे मॉडर्न फ़ॉर्मैट में बदलें.

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

असर

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

वेबसाइट एक: इसमें Imgix CDN के ज़रिए दिखाई गई इमेज वाले नेटिव <img> एलिमेंट का इस्तेमाल किया जाता है (डिफ़ॉल्ट कॉन्फ़िगरेशन विकल्पों के साथ).

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

फ़िल्मस्ट्रिप की तुलना: वेबसाइट पहली, जिसमें नेटिव इमेज टैग हैं और वेबसाइट दो पर ऐंग्युलर इमेज डायरेक्टिव के साथ.

टीम ने पार्टनर के साथ मिलकर, इस बात की पुष्टि की कि इमेज डायरेक्टिव की मदद से, रीयल एंटरप्राइज़ Angular ऐप्लिकेशन पर परफ़ॉर्मेंस का क्या असर पड़ता है.

इनमें से एक पार्टनर Land's End था. यह उम्मीद की गई थी कि उनकी साइट, ऐसे नतीजों के लिए अच्छा टेस्ट केस होगा जो असली ऐप्लिकेशन देख सकते हैं.

इमेज डायरेक्टिव का इस्तेमाल करने से पहले और बाद में, Lighthouse Lab टेस्टिंग को उनके QA एनवायरमेंट पर किया गया. डेस्कटॉप पर, उनके मीडियन एलसीपी 12.0 से घटकर 3.0 सेकंड हो गए, जो एलसीपी में 75% का सुधार है. मोबाइल पर, मीडियन एलसीपी 20.2 से घटकर 12.0 सेकंड (40.6% सुधार) हो गया.

आने वाले समय का रोडमैप

ऐंग्युलर इमेज डायरेक्टिव के लिए यह डिज़ाइन का सिर्फ़ पहला हिस्सा है. आने वाले समय में लॉन्च होने वाले वर्शन के लिए, इस तरह के और भी कई फ़ीचर प्लान किए गए हैं. इनमें ये शामिल हैं:

  • रिस्पॉन्सिव इमेज के लिए बेहतर सुविधा:

    फ़िलहाल, NgOptimizedImage में srcset का इस्तेमाल किया जा सकता है. हालांकि, हर इमेज के लिए, srcset और sizes एट्रिब्यूट को मैन्युअल तौर पर देना होगा. आने वाले समय में, यह डायरेक्टिव अपने-आप srcset और sizes एट्रिब्यूट जनरेट कर सकता है.

  • संसाधनों के लिए अपने-आप निर्देश डालना

    ज़रूरी एलसीपी इमेज के लिए, पहले से कनेक्ट और पहले से लोड किए गए टैग जनरेट करने के लिए, ऐंग्युलर सीएलआई के साथ इंटिग्रेट करना मुमकिन हो सकता है.

  • एंगुलर एसएसआर के लिए सहायता

    एमवीपी वर्शन को, ऐंग्युलर सीएसआर की पाबंदियों को ध्यान में रखकर बनाया गया है. हालांकि, ऐंग्युलर एसएसआर (ऐंगुलर/यूनिवर्सल) के लिए इमेज ऑप्टिमाइज़ेशन के तरीकों को एक्सप्लोर करना भी अहम होगा.

  • डेवलपर अनुभव में सुधार

    NgOptimizedImage के लिए ज़रूरी है कि हर इमेज के लिए width और height एट्रिब्यूट दिए गए हों. हालांकि, हर इमेज के लिए इन्हें तय करना कुछ डेवलपर के लिए मुश्किल हो सकता है. आने वाले समय में, डेवलपर के अनुभव को और बेहतर बनाया जा सकता है. इसके बारे में यहां बताया गया है:

    1. एक और मोड ("fill" Next.js में इमेज लेआउट विकल्प की तरह) के साथ काम करता है जिसे तय करने के लिए चौड़ाई/ऊंचाई की साफ़ तौर पर ज़रूरत न हो.
    2. इमेज के असल डाइमेंशन तय करके, लोकल इमेज की चौड़ाई और ऊंचाई अपने-आप सेट करने के लिए, सीएलआई इंटिग्रेशन का इस्तेमाल करना.

नतीजा

Angular इमेज डायरेक्टिव, डेवलपर के लिए अलग-अलग चरणों में उपलब्ध होंगे. इसकी शुरुआत, v14.2.0 में डेवलपर के लिए झलक दिखाने वाले वर्शन के साथ होगी. NgOptimizedImage को आज़माएं और सुझाव दें!

इसके लिए, केटी हेंपेनियस और एलेक्स कैसल का धन्यवाद.