Ottimizzazione delle immagini con la direttiva Angular Image

Kara Erickson
Kara Erickson
Leena Sohoni
Leena Sohoni

A maggio 2022, i team Aurora e Angular hanno annunciato che avrebbero collaborato a una direttiva relativa alle immagini per Angular. La direttiva è stata rilasciata di recente per la preview per sviluppatori nell'ambito di Angular v14.2. Questo post spiega in che modo la nuova direttiva immagine NgOptimizedImage supporta l'ottimizzazione delle immagini in Angular.

Sfondo

Le immagini sono un componente comune e fondamentale dell'esperienza utente web, con il 99,9% delle pagine web che generano richieste di una o più immagini. Le immagini sono anche il fattore più significativo per il peso della pagina, costituendo una media di 982 kilobyte per pagina.

A causa dell'aumento del numero e delle dimensioni delle immagini, le immagini possono ostacolare le prestazioni delle pagine web e influire sulle metriche di Core Web Vitals. Nel 2021, per il 79,4% delle pagine desktop, un'immagine era l'elemento Largest Contentful Paint (LCP). La ricerca di immagini ottimizzate è quindi diventata uno sforzo costante per molti di noi.

Il team di Aurora crede nell'utilizzo della potenza dei framework per fornire soluzioni integrate alle sfide comuni degli sviluppatori. Il loro primo approccio allo spazio di ottimizzazione delle immagini è stato il componente immagine Next.js. Ha considerato questo componente come un banco di prova per capire se il miglioramento dell'esperienza degli sviluppatori (DX) nell'ottimizzazione delle immagini potrebbe portare a risultati positivi in termini di prestazioni per più app che utilizzano framework.

La prima serie di risultati dell'utente Next.js Leboncoin è stata incoraggiante. Leboncoin ha registrato un miglioramento significativo dell'LCP (da 2,4 a 1,7 secondi) dopo aver iniziato a utilizzare next/image. La successiva adozione di next/image nella community ha svolto un ruolo nell'aumento delle origini Next.js che hanno raggiunto le soglie LCP. Ben presto sono arrivate richieste di funzionalità simili in altri framework, tra cui Angular.

Aurora si è pertanto consultata con Angular e Nuxt per realizzare un prototipo di componenti delle immagini per questi framework. Il componente Nuxt Image è stato rilasciato l'anno scorso. Ora è stata rilasciata la direttiva immagine Angular (NgOptimizedImage) per portare le impostazioni predefinite di ottimizzazione delle immagini ad Angular.

Opportunità

Angular è uno dei principali framework JavaScript utilizzati oggi dagli sviluppatori. Viene utilizzato da più di 50.000 origini sottoposte a scansione da HTTPArchive su dispositivi mobili e vanta quasi 3 milioni di download settimanali su NPM.

LCP per i siti web Angular nell'ultimo anno.

Se guardiamo ai punteggi Core Web Vitals, la percentuale di origini Angular che soddisfano le soglie LCP "buone" deve ancora essere migliorata. A giugno 2022, solo il 18,74% dei siti Angular aveva un buon LCP su dispositivi mobili. Poiché le immagini sono l'elemento LCP per oltre il 70% delle pagine web su dispositivi mobili e computer, le immagini LCP non ottimizzate potrebbero essere una delle cause principali di un LCP peggiore sui siti web Angular.

La direttiva di immagine Angular è stata progettata per contribuire a migliorare questi numeri.

MVP per la direttiva NgOptimizedImage

L'MVP della direttiva immagine di Angular si basa sulle lezioni apprese dai componenti immagine che Aurora ha creato finora, adattando al contempo il design all'esperienza di rendering lato client di Angular. Molti dei problemi di ottimizzazione delle immagini standard sono stati risolti da:

  • Fornire impostazioni predefinite efficaci.
  • Generare errori o avvisi per garantire la conformità alle best practice.

I punti salienti del design sono i seguenti:

  1. Caricamento lento intelligente

    Le immagini invisibili all'utente al caricamento della pagina (ad esempio le immagini sotto la piega o le immagini del carosello nascoste) dovrebbero idealmente essere caricate in modo lazy. Il caricamento lento libera le risorse del browser per caricare altri testi, contenuti multimediali o script critici. La maggior parte delle immagini non è critica e dovrebbe essere caricata in modo lazy, ma solo il 7,8% delle pagine ha utilizzato il caricamento lazy nativo nel 2021.

    La direttiva immagine Angular carica in modo lazy le immagini non critiche per impostazione predefinita e carica in modo eager solo le immagini contrassegnate appositamente come priority. In questo modo, la maggior parte delle immagini presenta un comportamento di caricamento ottimale.

  2. Assegnazione della priorità alle immagini critiche

    Aggiunta di suggerimenti per le risorse (ad es. preload o preconnect) per dare la priorità al caricamento delle immagini critiche è una best practice consigliata. Tuttavia, la maggior parte delle app non le utilizza. Secondo l'Almanacco del web 2021, solo il 12,7% delle pagine mobile utilizza i suggerimenti di preconnessione e solo il 22,1% delle pagine mobile utilizza i suggerimenti di precaricamento.

    La direttiva relativa alle immagini agisce su due fronti quando le immagini sono contrassegnate come prioritarie.

    • La priorità di recupero dell'immagine viene impostata su "high", in modo che il browser sappia che deve scaricare l'immagine con una priorità elevata.
    • In modalità di sviluppo, un controllo di runtime conferma che è stato incluso un suggerimento della risorsa preconnect corrispondente all'origine dell'immagine.

    In modalità di sviluppo, la direttiva utilizza anche l'API PerformanceObserver per verificare che l'immagine LCP sia stata contrassegnata come priority come previsto. Se non è contrassegnato come priority, viene generato un errore che indica allo sviluppatore di aggiungere l'attributo priority all'immagine LCP.

    In definitiva, questa combinazione di automazione e conformità garantisce che l'immagine LCP abbia un suggerimento preconnect, un valore dell'attributo fetchpriority pari a high e non sia caricata in modo lazy.

  3. Configurazione ottimizzata per gli strumenti per le immagini più diffusi

    Per le applicazioni Angular è consigliabile utilizzare CDN di immagini, che spesso forniscono servizi di ottimizzazione per impostazione predefinita.

    La direttiva incoraggia l'utilizzo delle CDN di immagini fornendo un'esperienza utente (DX) particolarmente accattivante per configurarle nell'app. Supporta un'API loader che ti consente di definire il provider CDN e l'URL base nella configurazione. Una volta configurato, devi solo definire il nome della risorsa nel markup. Ad esempio,

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

    Ciò equivale a includere i seguenti tag immagine e riduce il markup che gli sviluppatori devono includere per ogni immagine.

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

    La direttiva image fornisce caricatori integrati con una configurazione ottimale per le CDN di immagini più utilizzate. Questi caricatori formattano automaticamente gli URL immagine per garantire che per ogni CDN vengano utilizzate le impostazioni di compressione e formato delle immagini consigliate.

  4. Errori e avvisi integrati

    Oltre alle ottimizzazioni integrate sopra indicate, la direttiva include anche controlli integrati per garantire che gli sviluppatori abbiano seguito le best practice consigliate nel markup delle immagini. L'istruzione image esegue i seguenti controlli.

    1. Immagini senza dimensioni: l'istruzione image genera un errore se il markup dell'immagine non ha definito una larghezza e un'altezza esplicite. Le immagini senza dimensioni possono causare variazioni del layout, che influiscono sulla metrica Variazione layout cumulativa (CLS) della pagina. La best practice consigliata per evitare questo problema è specificare gli attributi width e height per le immagini.

    2. Proporzioni: la direttiva image genera un errore per informare gli sviluppatori se le proporzioni di width:height definite in HTML non sono vicine alle proporzioni effettive dell'immagine visualizzata. Ciò può causare la distorsione dell'immagine sullo schermo. Ciò può accadere se

      1. Per errore hai definito le dimensioni sbagliate (larghezza o altezza) o
      2. Se nel CSS hai definito una dimensione in base alla percentuale, ma non l'altra (ad esempio, width: 100% ha bisogno di height: auto per garantire che l'immagine cresca in entrambe le dimensioni).
    3. Immagini di grandi dimensioni: se l'immagine non definisce un attributo srcset e l'immagine intrinseca è notevolmente più grande dell'immagine visualizzata, la direttiva mostrerà un avviso che suggerisce l'utilizzo degli attributi srcset e sizes.

    4. Densità delle immagini: la direttiva restituirà un errore se provi a includere un'immagine in srcset con una densità di pixel superiore a 3x. In genere, i descrittori superiori a 2x non sono consigliati perché hanno la conseguenza indesiderata di costringere i dispositivi mobili ad alta risoluzione a scaricare immagini enormi. Inoltre, l'occhio umano non riesce a distinguere una grande differenza oltre il doppio.

Sfide

Adattare le strategie di ottimizzazione delle immagini in modo che funzionino in un framework lato client era una sfida principale nella progettazione di NgOptimizedImage. L'esperienza di rendering predefinita su Next.js è il rendering lato server (SSR) o la generazione di siti statici (SSG), mentre su Angular è il rendering lato client (CSR). Anche se Angular supporta una libreria SSR angular/universal, la maggior parte delle app Angular (~60%) utilizza CSR.

La direttiva image è interamente creata per il CSR in modo da allinearsi al caso d'uso tipico nelle app Angular. Questo ha definito ulteriori vincoli e il team ha dovuto ripensare a come creare ottimizzazioni specifiche per le app CSR.

Ecco alcune delle sfide incontrate:

  1. Suggerimenti per le risorse di supporto

    Il precaricamento degli asset critici consente al browser di rilevarli prima. Tuttavia, l'inclusione di suggerimenti di risorse nelle app Angular è complicato perché:

    Aggiunta manuale: per gli sviluppatori è difficile aggiungere manualmente l'indicazione della risorsa preload. Angular utilizza un file index.html condiviso per l'intero progetto o per tutte le route del sito web. Pertanto, il valore <head> del documento è lo stesso per ogni route (almeno al momento della pubblicazione). Se aggiungi un hint preload a <head>, la risorsa verrà precaricata per tutte le route anche dove non è richiesta. Pertanto, l'aggiunta manuale di suggerimenti preload non è consigliata.

    Aggiunta automatica durante il rendering: l'utilizzo del framework per aggiungere suggerimenti di precaricamento all'intestazione del documento durante il rendering in un'app CSR non è utile. Poiché il rendering avviene dopo il download ed esecuzione di JavaScript, <head> verrà visualizzato troppo tardi per avere valore.

    Per la prima versione della direttiva, una combinazione di suggerimenti preconnect e fetchpriority serve per dare la priorità all'immagine al posto di un preload. Tuttavia, Aurora sta attualmente collaborando con il team di Angular CLI per abilitare l'iniezione automatica dei suggerimenti sulle risorse in fase di compilazione. Continua a seguirci.

  2. Ottimizzazione delle dimensioni e del formato delle immagini sul server

    Poiché le app Angular hanno in genere un rendering lato client, le immagini sul file system non possono essere compresse al momento della richiesta e vengono pubblicate così come sono. Per questo motivo, è consigliabile utilizzare CDN di immagini per comprimere le immagini e convertirle in formati moderni come WebP o AVIF on demand.

    Anche se la direttiva non applica l'uso delle CDN di immagini, ti consigliamo vivamente di utilizzarle con l'istruzione e i suoi caricatori integrati garantiscono che vengano utilizzate le opzioni di configurazione corrette.

Impatto

La seguente demo mostra la differenza che la direttiva image di Angular può fare sul rendimento delle immagini. Mette a confronto due siti web:

Sito web uno: utilizza elementi <img> nativi con immagini pubblicate tramite la rete CDN Imgix (con opzioni di configurazione predefinite).

Secondo sito web: utilizza la direttiva image per tutte le immagini. Include anche le ottimizzazioni consigliate direttamente dagli avvisi o dagli errori generati dall'istruzione.

Confronto tra pellicola: il sito web 1 con tag immagine nativi e il sito web 2 con la direttiva sull&#39;immagine Angular.

Il team ha collaborato con i partner per convalidare l'impatto sulle prestazioni della direttiva relativa alle immagini sulle applicazioni Angular reali.

Uno di questi partner era Land's End. Ci si aspettava che il suo sito fosse un buon caso di test per i risultati che potrebbero essere visualizzati dalle applicazioni reali.

I test di Lighthouse Lab sono stati eseguiti nell'ambiente di QA prima e dopo l'utilizzo della direttiva delle immagini. Su computer, il valore LCP mediano è diminuito da 12,0 secondi a 3,0 secondi, con un miglioramento del 75%. Sui dispositivi mobili, il valore mediano LCP è diminuito da 20,2 secondi a 12 secondi (miglioramento del 40,6%).

Roadmap futura

Questa è solo la prima parte della progettazione per la direttiva Angular Image. Sono previste molte altre funzionalità per le versioni future, tra cui:

  • Migliore supporto per le immagini adattabili:

    Al momento NgOptimizedImage supporta l'utilizzo di srcset, ma gli attributi srcset e sizes devono essere forniti manualmente per ogni immagine. In futuro, l'istruzione potrebbe generare automaticamente gli attributi srcset e sizes.

  • Inserimento automatico di suggerimenti per le risorse

    Potrebbe essere possibile integrarsi con l'interfaccia a riga di comando Angular per generare tag di preconnessione e precaricare per immagini LCP critiche.

  • Supporto di Angular SSR

    La versione MVP è progettata tenendo conto dei vincoli di Angular CSR, ma sarà anche importante esplorare le soluzioni di ottimizzazione delle immagini per Angular SSR (angular/universal).

  • Miglioramenti all'esperienza degli sviluppatori

    NgOptimizedImage richiede che gli attributi width e height siano specificati per ogni immagine. Tuttavia, specificarli per ogni immagine potrebbe essere faticoso per alcuni sviluppatori. Ecco le potenzialità di miglioramento dell'esperienza degli sviluppatori nella prossima iterazione:

    1. Supporta una modalità aggiuntiva (simile all'opzione di layout delle immagini"fill" in Next.js) che non richiede la definizione di larghezza/altezza esplicite.
    2. Utilizzo dell'integrazione della CLI per impostare automaticamente la larghezza e l'altezza delle immagini locali determinando le dimensioni effettive dell'immagine.

Conclusione

La direttiva di immagine Angular sarà disponibile per gli sviluppatori in più fasi, a partire dalla versione di anteprima per sviluppatori nella v14.2.0. Prova NgOptimizedImage e lascia un feedback.

Un ringraziamento speciale a Katie Hempenius e Alex Castle per il loro contributo.