Optimiser les images avec la directive Angular Image

Kara Erickson
Kara Erickson
Leena Sohoni
Leena Sohoni

En mai 2022, les équipes Aurora et Angular ont annoncé leur collaboration sur une directive sur les images pour Angular. Cette directive a été publiée récemment pour la version Preview développeur dans le cadre d'Angular v14.2. Cet article explique comment la nouvelle directive d'image NgOptimizedImage permet l'optimisation des images dans Angular.

Contexte

Les images sont un élément commun et essentiel de l'expérience utilisateur sur le Web.En effet, 99,9% des pages Web génèrent des demandes pour une ou plusieurs images. Les images sont également les personnes qui contribuent le plus au poids de la page, avec une médiane de 982 kilo-octets par page.

En raison de leur nombre et de leur taille croissants, les images peuvent nuire aux performances des pages Web et affecter les métriques Core Web Vitals. Pour 79,4% des pages pour ordinateur, les images représentaient l'élément LCP (Largest Contentful Paint) en 2021. La recherche d'images optimisées est donc devenue un défi permanent pour beaucoup d'entre nous.

L'équipe d'Aurora croit en l'exploitation de la puissance des frameworks pour fournir des solutions intégrées aux défis courants des développeurs. Leur première entrée dans l'espace d'optimisation d'images a été le composant Image Next.js. Elle a considéré ce composant comme un terrain de test pour déterminer si l'amélioration de l'expérience de développement des images pouvait améliorer les performances d'un plus grand nombre d'applications utilisant des frameworks.

Les premiers résultats provenant de l'utilisateur Next.js Leboncoin étaient encourageants. Leboncoin a constaté une amélioration significative du LCP (de 2,4 s à 1,7 s) après avoir commencé à utiliser next/image. L'adoption ultérieure de next/image dans la communauté a contribué à augmenter le nombre d'origines Next.js atteignant les seuils LCP. Très vite, des demandes de fonctionnalités similaires ont été introduites dans d'autres frameworks, dont Angular.

Par conséquent, Aurora a consulté Angular et Nuxt pour prototyper les composants d'image pour ces frameworks. Le composant d'image Nuxt est sorti l'année dernière. Publication de la directive d'image Angular (NgOptimizedImage) pour appliquer les valeurs par défaut d'optimisation des images à Angular.

Opportunité

Angular est l'un des principaux frameworks JavaScript utilisés actuellement par les développeurs. Il est utilisé par plus de 50 000 origines explorées par HTTPArchive sur mobile et compte près de 3 millions de téléchargements hebdomadaires sur NPM.

LCP pour les sites Web Angular au cours de l'année écoulée.

Compte tenu des scores Core Web Vitals, le pourcentage d'origines Angular ayant atteint les "bons" seuils de LCP doit encore être retravaillé. En juin 2022, seuls 18,74% des sites Angular présentaient un bon LCP sur mobile. Étant donné que les images constituent l'élément LCP de plus de 70% des pages Web sur mobile et ordinateur, les images LCP non optimisées peuvent être l'une des principales causes d'un LCP faible sur les sites Web Angular.

La directive sur les images Angular a été conçue pour améliorer ces chiffres.

MVP pour la directive NgOptimizedImage

Le MVP de la directive sur les images Angular s'appuie sur les enseignements tirés des composants d'image qu'Aurora a créés à ce jour, tout en adaptant la conception à l'expérience de rendu côté client d'Angular. De nombreux problèmes standards d'optimisation d'images ont été résolus, à l'aide des méthodes suivantes:

  • Fournir des valeurs par défaut fortes.
  • Générer des erreurs ou des avertissements pour garantir le respect des bonnes pratiques

Les points forts de la conception sont les suivants:

  1. Chargement différé intelligent

    Les images qui ne sont pas visibles par l'utilisateur lors du chargement de la page (par exemple, les images en dessous de la ligne de flottaison ou les images masquées dans un carrousel) doivent idéalement être chargées de manière différée. Le chargement différé libère des ressources du navigateur pour le chargement d'autres textes, contenus multimédias ou scripts essentiels. La plupart des images ne sont pas critiques et doivent être chargées de manière différée, mais seulement 7,8% des pages utilisaient le chargement différé natif en 2021.

    La directive d'image Angular charge les images non critiques par défaut et ne charge hâtivement que les images spécialement marquées comme priority. Cela garantit que la plupart des images présentent un comportement de chargement optimal.

  2. Hiérarchisation des images critiques

    Ajouter des indices de ressources (par exemple, preload ou preconnect) pour prioriser le chargement des images critiques est une bonne pratique recommandée. Cependant, la plupart des applications ne les utilisent pas. Selon l'étude Web Almanac de 2021, seulement 12,7% des pages mobiles utilisent des conseils de préconnexion et seulement 22,1% des pages mobiles.

    La directive relative aux images agit sur deux fronts lorsque les images sont marquées comme prioritaires.

    • Il définit la priorité de récupération de l'image sur "high" afin que le navigateur sache qu'il doit télécharger l'image avec une priorité élevée.
    • En mode Développement, une vérification d'exécution confirme qu'une optimisation de ressource preconnect correspondant à l'origine de l'image a été incluse.

    En mode Développement, la directive utilise également l'API PerformanceObserver pour vérifier que l'image LCP a été marquée comme priority comme prévu. S'il n'est pas marqué priority, une erreur est générée, demandant au développeur d'ajouter l'attribut priority à l'image LCP.

    En fin de compte, cette combinaison d'automatisation et de conformité garantit que l'image LCP comporte un indice preconnect, une valeur d'attribut fetchpriority de high et qu'elle n'est pas chargée de manière différée.

  3. Configuration optimisée pour les outils de gestion des images les plus courants

    Il est recommandé que les applications Angular utilisent des CDN d'images, qui fournissent souvent des services d'optimisation par défaut.

    Cette directive encourage l'utilisation de CDN pour les images en offrant une expérience développeur (DX) particulièrement attrayante pour les configurer dans l'application. Elle prend en charge une API de chargement qui vous permet de définir le fournisseur CDN et votre URL de base dans votre configuration. Une fois le composant configuré, il vous suffit de définir son nom dans le balisage. Par exemple,

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

    Cela équivaut à inclure les balises d'image suivantes et réduit le balisage que les développeurs doivent inclure pour chaque image.

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

    La directive d'image fournit des chargeurs intégrés avec une configuration optimale pour les CDN d'images les plus courants. Ces chargeurs mettent automatiquement en forme les URL des images afin de garantir que le format d'image et les paramètres de compression recommandés sont utilisés pour chaque CDN.

  4. Erreurs et avertissements intégrés

    Outre les optimisations intégrées ci-dessus, la directive comporte des vérifications intégrées pour s'assurer que les développeurs ont suivi les bonnes pratiques recommandées pour le balisage des images. La directive "image" effectue les vérifications suivantes.

    1. Images non dimensionnées:la directive "image" génère une erreur si le balisage d'image n'a pas défini de largeur et de hauteur explicites. Les images non dimensionnées peuvent entraîner des décalages de mise en page et avoir une incidence sur la métrique CLS (Cumulative Layout Shift). Pour éviter cela, il est recommandé de spécifier les attributs width et height pour les images.

    2. Format:la directive d'image génère une erreur pour indiquer aux développeurs si le format de width:height défini dans le code HTML est différent du format réel de l'image affichée. L'image peut alors être déformée à l'écran. Cela peut se produire si

      1. Vous avez défini des dimensions incorrectes (largeur ou hauteur) par erreur.
      2. Si vous avez défini une dimension en pourcentage dans votre code CSS, mais pas l'autre (par exemple, width: 100% a besoin de height: auto pour que l'image s'agrandisse dans les deux dimensions).
    3. Images surdimensionnées:si l'image ne définit pas de srcset et que l'image intrinsèque est considérablement plus grande que l'image rendue, la directive affiche un avertissement suggérant l'utilisation des attributs srcset et sizes.

    4. Densité d'image:la directive génère une erreur si vous essayez d'inclure dans l'élément srcset une image avec une densité de pixels supérieure à 3x. Les descripteurs supérieurs à 2x ne sont généralement pas recommandés, car cela a pour effet imprévu de forcer les appareils mobiles haute résolution à télécharger des images volumineuses. De plus, l'œil humain ne parvient pas à distinguer une différence supérieure à deux fois.

défis

Adapter les stratégies d'optimisation des images à un framework côté client représentait un défi majeur lors de la conception de NgOptimizedImage. Le rendu par défaut sur Next.js est le rendu côté serveur (SSR) ou la génération de sites statiques (SSG), tandis que dans Angular, le rendu côté client (CSR) est utilisé par défaut. Même si Angular est compatible avec une bibliothèque SSR (angulaire/universelle), la plupart des applications Angular (environ 60%) utilisent CSR.

La directive "image" est entièrement conçue pour la requête de signature de certificat pour s'aligner sur le cas d'utilisation typique des applications Angular. Cela imposait des contraintes supplémentaires, et l'équipe a dû repenser la façon de créer des optimisations spécifiques pour les applications de conseiller clientèle.

Voici quelques-uns des problèmes rencontrés:

  1. Fournir des indications sur les ressources

    Le préchargement des éléments critiques permet au navigateur de les détecter plus tôt. Cependant, il est compliqué d'inclure des indices de ressources dans les applications Angular, car:

    Ajout manuel: il est difficile pour les développeurs d'ajouter manuellement l'indice de ressource preload. Angular utilise un fichier index.html partagé pour l'ensemble du projet ou pour toutes les routes du site Web. Ainsi, le <head> du document est le même pour chaque itinéraire (au moins au moment de la présentation). Ajouter une indication preload à <head> signifie que la ressource est préchargée pour toutes les routes, même si elle n'est pas requise. Par conséquent, nous vous déconseillons d'ajouter manuellement preload indications.

    Ajout automatique pendant le rendu:l'utilisation du framework pour ajouter des indications de préchargement à l'en-tête du document pendant l'affichage dans une application CSR n'aide pas. Étant donné que l'affichage a lieu après le téléchargement et l'exécution du code JavaScript, <head> s'affiche trop tard pour prendre une valeur quelconque.

    Pour la première version de la directive, une combinaison d'annotations preconnect et fetchpriority sert à donner la priorité à l'image au lieu d'une preload. Cependant, Aurora collabore actuellement avec l'équipe de la CLI Angular pour activer l'injection automatique d'indicateurs de ressources au moment de la compilation. Tenez-vous informé !

  2. Optimiser la taille et le format des images sur le serveur

    Étant donné que les applications Angular sont généralement affichées côté client, les images du système de fichiers ne peuvent pas être compressées au moment de la requête et sont diffusées telles quelles. Il est donc recommandé d'utiliser des CDN pour les images afin de compresser les images et de les convertir dans des formats modernes tels que WebP ou AVIF à la demande.

    Bien que la directive n'impose pas l'utilisation d'images CDN, nous vous recommandons vivement de les utiliser avec la directive. Ses chargeurs intégrés garantissent que les options de configuration appropriées sont utilisées.

Impact

La démonstration suivante montre l'impact de la directive d'image Angular sur les performances des images. Il compare deux sites Web:

Site Web 1:utilise des éléments <img> natifs avec des images diffusées via le CDN Imgix (avec les options de configuration par défaut).

Site Web 2:utilisez la directive "image" pour toutes les images. Elle inclut également les optimisations recommandées directement par les avertissements ou les erreurs générés par la directive.

Comparaison de la pellicule: site Web 1 avec des balises d&#39;image natives et site Web 2 avec la directive d&#39;image Angular.

L'équipe a collaboré avec des partenaires pour valider l'impact de la directive d'images sur les performances des applications Angular d'entreprise réelles.

L'un de ces partenaires était Land's End. On s'attendait à ce que leur site soit un bon scénario de test pour obtenir des résultats que de vraies applications pourraient obtenir.

Des tests Lighthouse en laboratoire ont été effectués dans l'environnement de contrôle qualité avant et après l'utilisation de la directive sur les images. Sur les ordinateurs, le LCP médian a diminué de 12 s à 3 s, ce qui représente une amélioration de 75% du LCP. Sur les mobiles, le LCP médian est passé de 20,2 s à 12 s (amélioration de 40,6 %).

Feuille de route future

Il ne s'agit que du premier volet de la conception de la directive sur les images Angular. De nombreuses autres fonctionnalités sont prévues pour les futures versions, y compris:

  • Meilleure compatibilité avec les images responsives:

    NgOptimizedImage prend actuellement en charge l'utilisation de srcset, mais les attributs srcset et sizes doivent être fournis manuellement pour chaque image. À l'avenir, la directive pourrait générer automatiquement les attributs srcset et sizes.

  • Injection automatique de suggestions de ressources

    L'intégration à la CLI Angular permet de générer des tags de préconnexion et de préchargement pour les images LCP critiques.

  • Compatibilité avec Angular SSR

    La version MVP est conçue en tenant compte des contraintes CSR Angular, mais il sera également important d'explorer les solutions d'optimisation des images pour Angular SSR (angulaire/universel).

  • Améliorations apportées à l'expérience des développeurs

    NgOptimizedImage exige que les attributs width et height soient spécifiés pour chaque image. Toutefois, leur spécification pour chaque image peut s'avérer fastidieux pour certains développeurs. Il est possible d'améliorer l'expérience des développeurs dans la prochaine itération comme suit:

    1. Prise en charge d'un mode supplémentaire (semblable à l'option de mise en page d'image fill dans Next.js) qui ne nécessite pas de définir une largeur/hauteur explicite.
    2. Utiliser l'intégration de la CLI pour définir automatiquement la largeur et la hauteur des images locales en déterminant leurs dimensions réelles

Conclusion

La directive sur les images Angular sera mise à la disposition des développeurs par étapes, à commencer par la version Preview développeur dans la version 14.2.0. Essayez NgOptimizedImage et laissez-nous vos commentaires

Nous remercions particulièrement Katie Hempenius et Alex Castle pour leur contribution.