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

कारा एरिकसन
कारा एरिकसन
लीना सोहोनी
लीना सोहोनी

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

बैकग्राउंड

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

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

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 फ़्रेमवर्क में से एक है जिन्हें आज डेवलपर इस्तेमाल करते हैं. इसे मोबाइल पर HTTPArchive की मदद से क्रॉल किए गए 50 हज़ार से ज़्यादा ऑरिजिन के लिए इस्तेमाल किया जाता है. इसके अलावा, एनपीएम पर हर हफ़्ते करीब 30 लाख वीडियो डाउनलोड किए जाते हैं.

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

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

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

NgOptimizedImage डायरेक्टिव का एमवीपी

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

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

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

  1. स्मार्ट लेज़ी लोडिंग

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

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

  2. क्रिटिकल इमेज को प्राथमिकता देना

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

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

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

    डेवलपमेंट मोड में, डायरेक्टिव यह पुष्टि करने के लिए Performanceनिगरानी एपीआई का भी इस्तेमाल करता है कि एलसीपी इमेज को उम्मीद के मुताबिक 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. बिना साइज़ वाली इमेज: अगर इमेज मार्कअप में साफ़ तौर पर चौड़ाई और ऊंचाई तय नहीं की गई है, तो इमेज डायरेक्टिव गड़बड़ी का मैसेज दिखाता है. साइज़ न दिखने वाली इमेज की वजह से, लेआउट में बदलाव हो सकते हैं. इससे, पेज की कुल लेआउट शिफ़्ट (सीएलएस) मेट्रिक पर असर पड़ सकता है. इसे रोकने का सबसे सही तरीका यह है कि इमेज में width और height एट्रिब्यूट के बारे में बताया जाना चाहिए.

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

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

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

चैलेंज

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

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

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

  1. संसाधनों से जुड़े संकेतों के साथ काम करना

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

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

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

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

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

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

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

असर

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

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

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

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

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

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

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

नतीजा

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

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