Afbeeldingen optimaliseren met de Angular Image-richtlijn

Kara Erickson
Kara Erickson
Leena Sohoni
Leena Sohoni

In mei 2022 maakten de teams van Aurora en Angular bekend dat ze zouden samenwerken aan een beeldrichtlijn voor Angular. De richtlijn is onlangs vrijgegeven voor preview voor ontwikkelaars als onderdeel van Angular v14.2. In dit bericht wordt besproken hoe de nieuwe afbeeldingsrichtlijn, NgOptimizedImage , afbeeldingsoptimalisatie in Angular ondersteunt.

Achtergrond

Afbeeldingen zijn een veelvoorkomend en cruciaal onderdeel van de webgebruikerservaring: 99,9% van de webpagina's genereert verzoeken om een ​​of meer afbeeldingen. Afbeeldingen leveren ook de grootste bijdrage aan het paginagewicht, met een gemiddelde van 982 kilobytes per pagina.

Vanwege hun groeiende aantal en omvang kunnen afbeeldingen de prestaties van webpagina's belemmeren en de Core Web Vitals -statistieken beïnvloeden. Voor 79,4% van de desktoppagina's was een afbeelding het grootste Contentful Paint ( LCP )-element in 2021. Het streven naar geoptimaliseerde afbeeldingen is dus voor velen van ons een constante inspanning geworden.

Het Aurora-team gelooft in het benutten van de kracht van frameworks om ingebouwde oplossingen te bieden voor algemene uitdagingen voor ontwikkelaars. Hun eerste uitstapje op het gebied van beeldoptimalisatie was de afbeeldingscomponent Next.js. Ze beschouwden dit onderdeel als een proeftuin voor de vraag of het verbeteren van de ontwikkelaarservaring (DX) van beeldoptimalisatie zou kunnen leiden tot prestatiewinst voor meer apps die frameworks gebruiken.

De eerste reeks resultaten van Next.js-gebruiker Leboncoin was bemoedigend. Leboncoin zag een aanzienlijke LCP-verbetering (van 2,4s naar 1,7s) nadat ze next/image begonnen te gebruiken. De daaropvolgende acceptatie van next/image in de gemeenschap speelde een rol in de toename van de oorsprong van Next.js die aan de LCP-drempels voldeed. Al snel waren er verzoeken om vergelijkbare functies in andere raamwerken, waaronder Angular .

Als gevolg hiervan overlegde Aurora met Angular en Nuxt om prototypen van beeldcomponenten voor deze raamwerken te maken. De Nuxt-beeldcomponent werd vorig jaar uitgebracht. Nu is de Angular-beeldrichtlijn ( NgOptimizedImage ) vrijgegeven om de standaardinstellingen voor beeldoptimalisatie naar Angular te brengen.

Mogelijkheid

Angular is een van de toonaangevende JavaScript-frameworks die tegenwoordig door ontwikkelaars worden gebruikt. Het wordt gebruikt door meer dan 50.000 van de origins die door HTTPArchive op mobiel worden gecrawld en beschikt over bijna 3 miljoen wekelijkse downloads op NPM.

LCP voor Angular-websites gedurende het afgelopen jaar.

Als we naar de Core Web Vitals-scores kijken, moet er nog gewerkt worden aan het percentage Angular-oorsprongen dat voldoet aan de ‘goede’ LCP-drempels. Slechts 18,74% van de Angular-sites had in juni 2022 een goede LCP op mobiel. Omdat afbeeldingen het LCP-element vormen voor meer dan 70% van de webpagina's op mobiel en desktop, kunnen niet-geoptimaliseerde LCP-afbeeldingen een van de belangrijkste oorzaken zijn van een slechtere LCP op Angular websites.

De Angular-beeldrichtlijn is ontworpen om deze cijfers te helpen verbeteren.

MVP voor de NgOptimizedImage-richtlijn

De MVP van de Angular-beeldrichtlijn bouwt voort op lessen uit de beeldcomponenten die Aurora tot nu toe heeft gebouwd, terwijl het ontwerp wordt aangepast aan de weergave-ervaring van Angular aan de clientzijde. Veel van de standaardproblemen met beeldoptimalisatie zijn opgelost door:

  • Het bieden van sterke standaarden.
  • Het genereren van fouten of waarschuwingen om naleving van best practices te garanderen.

De hoogtepunten van het ontwerp zijn als volgt:

  1. Intelligent lui laden

    Afbeeldingen die tijdens het laden van de pagina onzichtbaar zijn voor de gebruiker (bijvoorbeeld afbeeldingen onder de vouw of verborgen carrouselafbeeldingen) moeten idealiter 'lazy-loaded' zijn. Lazy Load maakt browserbronnen vrij om andere kritische tekst, media of scripts te laden. De meeste afbeeldingen zijn niet-kritisch en zouden lazy-loaded moeten zijn, maar in 2021 gebruikte slechts 7,8% van de pagina's native lazyloading.

    De Angular image-richtlijn laadt standaard niet-kritieke afbeeldingen en laadt alleen gretig afbeeldingen die speciaal als priority zijn gemarkeerd. Dit zorgt ervoor dat de meeste afbeeldingen optimaal laadgedrag vertonen.

  2. Prioritering van kritische beelden

    Het toevoegen van bronhints (bijvoorbeeld preload of preconnect ) om prioriteit te geven aan het laden van kritieke afbeeldingen is een aanbevolen best practice . De meeste apps maken er echter geen gebruik van. Volgens de Web Almanac 2021 gebruikt slechts 12,7% van de mobiele pagina's preconnect-hints en slechts 22,1% van de mobiele pagina's gebruikt preload-hints.

    De beeldrichtlijn werkt op twee fronten wanneer afbeeldingen als prioriteit worden gemarkeerd.

    • Het stelt de ophaalprioriteit van de afbeelding in op "high" zodat de browser weet dat hij de afbeelding met een hoge prioriteit moet downloaden.
    • In de ontwikkelingsmodus bevestigt een runtimecontrole dat er een preconnect resourcehint is opgenomen die overeenkomt met de oorsprong van de afbeelding.

    In de ontwikkelingsmodus gebruikt de richtlijn ook de PerformanceObserver API om te verifiëren dat de LCP-image zoals verwacht als priority is gemarkeerd. Als het niet gemarkeerd is met priority , wordt er een fout gegenereerd, waarin de ontwikkelaar wordt geïnstrueerd om het priority aan de LCP-image toe te voegen.

    Uiteindelijk zorgt deze combinatie van automatisering en conformiteit ervoor dat de LCP-image een preconnect hint heeft, een fetchpriority -attribuutwaarde van high en niet lui wordt geladen.

  3. Geoptimaliseerde configuratie voor populaire beeldtools

    Het wordt aanbevolen dat Angular-toepassingen image-CDN's gebruiken , die vaak standaard optimalisatieservices bieden.

    De richtlijn moedigt het gebruik van image-CDN’s aan door een bijzonder aantrekkelijke ontwikkelaarservaring (DX) te bieden om ze in de app te configureren. Het ondersteunt een loader-API waarmee u de CDN-provider en uw basis-URL in uw configuratie kunt definiëren. Eenmaal geconfigureerd, hoeft u alleen de itemnaam in de opmaak te definiëren. Bijvoorbeeld,

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

    Dit komt overeen met het opnemen van de volgende afbeeldingstags en vermindert de opmaak die ontwikkelaars voor elke afbeelding moeten toevoegen.

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

    De image-richtlijn biedt ingebouwde laders met optimale configuratie voor de meest populaire image-CDN's. Deze laders formatteren afbeeldings-URL's automatisch om ervoor te zorgen dat het aanbevolen afbeeldingsformaat en de compressie-instellingen voor elke CDN worden gebruikt.

  4. Ingebouwde fouten en waarschuwingen

    Naast de bovenstaande ingebouwde optimalisaties heeft de richtlijn ook ingebouwde controles om ervoor te zorgen dat ontwikkelaars de aanbevolen best practices in de afbeeldingsopmaak hebben gevolgd. De image-richtlijn voert de volgende controles uit.

    1. Afbeeldingen zonder grootte: de afbeeldingsrichtlijn genereert een fout als de afbeeldingsopmaak geen expliciete breedte en hoogte heeft gedefinieerd. Afbeeldingen zonder formaat kunnen lay-outverschuivingen veroorzaken, waardoor de statistiek Cumulatieve lay-outverschuiving ( CLS ) van de pagina wordt beïnvloed. De aanbevolen beste praktijk om dit te voorkomen is dat voor afbeeldingen de attributen width en height moeten worden gespecificeerd.

    2. Beeldverhouding: De afbeeldingsrichtlijn genereert een fout om ontwikkelaars te laten weten of de beeldverhouding van de width : height gedefinieerd in de HTML niet dicht bij de werkelijke beeldverhouding van de weergegeven afbeelding ligt. Hierdoor kan het beeld er vervormd uitzien op het scherm. Dit kan gebeuren als

      1. U heeft per ongeluk de verkeerde afmetingen (breedte of hoogte) gedefinieerd of
      2. Als u de ene dimensie per percentage in uw CSS hebt gedefinieerd, maar de andere niet ( width: 100% heeft bijvoorbeeld height: auto nodig om ervoor te zorgen dat de afbeelding in beide dimensies groeit).
    3. Overmaatse afbeeldingen: Als de afbeelding geen srcset definieert en de intrinsieke afbeelding aanzienlijk groter is dan de weergegeven afbeelding, zal de richtlijn een waarschuwing weergeven die het gebruik van de attributen srcset en sizes suggereert.

    4. Afbeeldingsdichtheid: de richtlijn geeft een foutmelding als u probeert een afbeelding in de srcset op te nemen met een pixeldichtheid van meer dan 3x . Descriptors hoger dan 2x worden over het algemeen niet aanbevolen, omdat dit het onbedoelde gevolg heeft dat mobiele apparaten met hoge resolutie worden gedwongen grote afbeeldingen te downloaden. Bovendien kan het menselijk oog eigenlijk niet veel verschil zien boven 2x .

Uitdagingen

Het aanpassen van beeldoptimalisatiestrategieën om te werken binnen een client-side raamwerk was een primaire uitdaging bij het ontwerpen van NgOptimizedImage . De standaard weergave-ervaring op Next.js is Server Side Rendering (SSR) of Static Site Generation (SSG), terwijl die op Angular Client Side Rendering (CSR) is. Hoewel Angular een SSR-bibliotheek ondersteunt ( hoekig/universeel ), gebruiken de meeste Angular-apps (~60%) CSR.

De beeldrichtlijn is volledig ontworpen om CSR aan te passen aan de typische use case in Angular-apps. Dit bracht extra beperkingen met zich mee en het team moest opnieuw nadenken over de manier waarop specifieke optimalisaties voor CSR-apps konden worden ontwikkeld.

Enkele van de uitdagingen die we tegenkomen zijn:

  1. Ondersteunende brontips

    Door kritieke assets vooraf te laden, kan de browser deze eerder ontdekken. Het opnemen van bronnenhints in Angular-apps is echter ingewikkeld omdat:

    Handmatige toevoeging : het is moeilijk voor ontwikkelaars om de preload bronhint handmatig toe te voegen. Angular gebruikt één gedeeld index.html bestand voor het gehele project of voor alle routes in de website. De <head> van het document is dus voor elke route hetzelfde (tenminste op het moment van serveren). Het toevoegen van een preload aan de <head> zou betekenen dat de bron voor alle routes vooraf wordt geladen, zelfs als deze niet nodig is. Het handmatig toevoegen van preload -hints wordt dus niet aanbevolen.

    Automatische toevoeging tijdens weergave: het gebruik van het raamwerk om vooraf geladen hints toe te voegen aan de kop van het document tijdens weergave in een CSR-app helpt niet. Omdat weergave plaatsvindt nadat JavaScript is gedownload en uitgevoerd, wordt de <head> te laat weergegeven om nog enige waarde te hebben.

    Voor de eerste versie van de richtlijn dient een combinatie van preconnect hints en fetchpriority hints om prioriteit te geven aan de afbeelding in plaats van een preload . Aurora werkt momenteel echter samen met het Angular CLI-team om automatische injectie van resource-hints tijdens het bouwen mogelijk te maken - houd het in de gaten!

  2. Optimalisatie van de afbeeldingsgrootte en -indeling op de server

    Omdat Angular-apps doorgaans aan de clientzijde worden weergegeven, kunnen afbeeldingen op het bestandssysteem niet op verzoek worden gecomprimeerd en worden ze weergegeven zoals ze zijn. Om deze reden wordt het gebruik van afbeeldings-CDN's aanbevolen om afbeeldingen te comprimeren en deze op aanvraag naar moderne formaten zoals WebP of AVIF te converteren.

    Hoewel de richtlijn het gebruik van image-CDN's niet afdwingt, wordt het sterk aangemoedigd om deze samen met de richtlijn te gebruiken. De ingebouwde laders zorgen ervoor dat de juiste configuratie-opties worden gebruikt.

Invloed

De volgende demo demonstreert het verschil dat de Angular-beeldrichtlijn kan maken voor de beeldprestaties. Het vergelijkt twee websites:

Website één: gebruikt native <img> -elementen met afbeeldingen die worden aangeboden via de Imgix CDN (met standaardconfiguratie-opties).

Website twee: gebruik de afbeeldingsrichtlijn voor alle afbeeldingen. Het omvat ook de optimalisaties die rechtstreeks worden aanbevolen door waarschuwingen of fouten die door de richtlijn worden gegenereerd.

Vergelijking van filmstrips: Website One met native afbeeldingstags versus Website Two met de Angular-afbeeldingsrichtlijn.

Het team werkte samen met partners om de prestatie-impact van de image-richtlijn op echte zakelijke Angular-applicaties te valideren.

Eén van deze partners was Land's End . Er werd verwacht dat hun site een goede testcase zou zijn voor resultaten die echte toepassingen zouden kunnen zien.

Lighthouse-laboratoriumtests werden uitgevoerd op hun QA-omgeving voor en na het gebruik van de image-richtlijn. Op desktops daalde hun gemiddelde LCP van 12,0 seconden naar 3,0 seconden, een verbetering van 75% in LCP. Op mobiel daalde de mediane LCP van 20,2 seconden naar 12,0 seconden (40,6% verbetering).

Toekomstige routekaart

Dit is pas de eerste aflevering van het ontwerp voor de Angular-beeldrichtlijn. Er zijn nog veel meer functies gepland voor toekomstige versies, waaronder:

  • Betere ondersteuning voor responsieve afbeeldingen:

    NgOptimizedImage ondersteunt momenteel het gebruik van srcset , maar de kenmerken srcset sizes moeten handmatig voor elke afbeelding worden opgegeven. In de toekomst zou de richtlijn de kenmerken srcset en sizes automatisch kunnen genereren.

  • Automatische injectie van hulpbronnenhints

    Het is mogelijk mogelijk om te integreren met de Angular CLI om preconnect- en preload-tags te genereren voor kritieke LCP-images.

  • Ondersteuning voor hoekige SSR

    De MVP-versie is ontworpen met inachtneming van de beperkingen van Angular CSR, maar het zal ook belangrijk zijn om oplossingen voor beeldoptimalisatie voor Angular SSR (hoekig/universeel) te onderzoeken.

  • Verbeteringen in de ervaring van ontwikkelaars

    NgOptimizedImage vereist dat voor elke afbeelding de kenmerken width en height worden opgegeven. Voor sommige ontwikkelaars kan het echter lastig zijn om deze voor elke afbeelding op te geven. Er is een potentieel om de ontwikkelaarservaring hier in de volgende iteratie als volgt te verbeteren:

    1. Ondersteuning van een extra modus (vergelijkbaar met de optie " fill " voor afbeeldingsindeling in Next.js ) waarvoor geen expliciete breedte/hoogte hoeft te worden gedefinieerd.
    2. Gebruik CLI-integratie om automatisch de breedte en hoogte voor lokale afbeeldingen in te stellen door de werkelijke afmetingen van de afbeelding te bepalen.

Conclusie

De Angular image-richtlijn zal in fasen beschikbaar zijn voor ontwikkelaars, te beginnen met de preview-versie voor ontwikkelaars in v14.2.0. Probeer NgOptimizedImage eens en laat feedback achter!

Met speciale dank aan Katie Hempenius en Alex Castle voor hun bijdrage.