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. Di recente, la direttiva è stata rilasciata per l'anteprima per gli sviluppatori come parte della versione 14.2 di Angular. Questo post spiega come la nuova istruzione immagine, NgOptimizedImage, supporti l'ottimizzazione delle immagini in Angular.

Contesto

Le immagini sono un componente comune e fondamentale dell'esperienza utente sul web: il 99, 9% delle pagine web genera richieste per una o più immagini. Le immagini sono anche i fattori che contribuiscono maggiormente al peso della pagina, con 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. Per il 79,4% delle pagine desktop, un'immagine è stata l'elemento Largest Contentful Paint (LCP) del 2021. La ricerca di immagini ottimizzate è quindi diventata uno sforzo costante per molti di noi.

Il team Aurora crede nello sfruttare la potenza dei framework per fornire soluzioni integrate a sfide comuni degli sviluppatori. La loro prima incursione nello spazio di ottimizzazione delle immagini è stata 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 di Next.js Leboncoin è stata incoraggiante. Leboncoin ha riscontrato un miglioramento significativo dell'LCP (da 2,4 secondi 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. Presto sono arrivate richieste per funzionalità simili in altri framework, una delle quali è 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 l'istruzione Angular image (NgOptimizedImage) per portare le impostazioni predefinite di ottimizzazione delle immagini in Angular.

Opportunity

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

LCP per i siti web Angular nell'ultimo anno.

Osservando i punteggi Core Web Vitals, la percentuale di origini Angular che soddisfano soglie LCP "buone" richiede ancora interventi. Solo il 18,74% dei siti Angular ha registrato un buon punteggio LCP sui dispositivi mobili a giugno 2022. 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 valore LCP più basso sui siti web Angular.

La direttiva Angular Image è stata progettata per migliorare questi valori.

MVP per la direttiva NgOptimizedImage

L'MVP della direttiva sulle immagini Angular si basa sulle lezioni ottenute dai componenti immagine che Aurora ha sviluppato fino a oggi, adattando il design all'esperienza di rendering lato client di Angular. Molti dei problemi di ottimizzazione delle immagini standard sono stati risolti da:

  • Fornisce valori predefiniti 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 durante il caricamento della pagina (ad esempio, immagini below the fold o immagini carosello nascoste) dovrebbero idealmente essere con caricamento lento. Il caricamento lento libera le risorse del browser per caricare altri testi, contenuti multimediali o script critici. La maggior parte delle immagini non sono fondamentali e dovrebbe essere con caricamento lento, ma solo il 7,8% delle pagine ha utilizzato il caricamento lento nativo nel 2021.

    L'istruzione Angular image carica le immagini non critiche per impostazione predefinita e carica solo con entusiasmo solo le immagini contrassegnate in modo speciale come priority. In questo modo, la maggior parte delle immagini presenta un comportamento di caricamento ottimale.

  2. Assegnazione della priorità alle immagini più importanti

    Aggiungi hint delle risorse (ad es. preload o preconnect) per dare la priorità al caricamento di immagini critiche è una best practice consigliata. Tuttavia, la maggior parte delle app non lo utilizza. Secondo Web Almanac del 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.

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

    In modalità di sviluppo, l'istruzione 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 che non venga caricato tramite caricamento lento.

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

    È consigliabile che le applicazioni Angular utilizzino CDN di immagini, che spesso forniscono servizi di ottimizzazione per impostazione predefinita.

    La direttiva incoraggia l'utilizzo di CDN di immagini offrendo un'esperienza di sviluppo (DX) particolarmente allettante per configurarle nell'app. Supporta un'API caricatore che consente di definire il provider CDN e l'URL di base nella configurazione. Dopo la configurazione, devi solo definire il nome dell'asset 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 ai caricatori integrati una configurazione ottimale per le CDN di immagini più popolari. 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 descritte, la direttiva prevede anche dei 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 relativa alle immagini 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 e influire sulla metrica CLS (Cumulative Layout Shift) della pagina. La best practice consigliata per evitare questo problema è di specificare gli attributi width e height per le immagini.

    2. Proporzioni:l'istruzione relativa all'immagine genera un errore per comunicare agli sviluppatori se le proporzioni di width:height definite nel codice HTML non sono simili a quelle effettive dell'immagine visualizzata. L'immagine potrebbe risultare distorta sullo schermo. Ciò può verificarsi se

      1. Hai definito le dimensioni errate (larghezza o altezza) per errore 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 aumenti in entrambe le dimensioni).
    3. Immagini troppo grandi: se l'immagine non definisce un valore srcset e l'immagine intrinseca è molto più grande dell'immagine visualizzata, l'istruzione mostrerà un avviso che suggerisce l'utilizzo degli attributi srcset e sizes.

    4. Densità immagine: l'istruzione genera un errore se tenti di includere un'immagine nell'elemento srcset con una densità di pixel superiore a 3x. I descrittori superiori a 2x in genere non sono consigliati perché ha la conseguenza involontaria di forzare i dispositivi mobili ad alta risoluzione a scaricare immagini di grandi dimensioni. Inoltre, l'occhio umano non è in grado di distinguere molte differenze rispetto a 2x.

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 relativa alle immagini è stata creata interamente per CSR in linea con il caso d'uso tipico delle 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 sulle 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: è difficile per gli sviluppatori aggiungere manualmente il suggerimento risorsa preload. Angular utilizza un file index.html condiviso per l'intero progetto o per tutti i percorsi nel sito web. Pertanto, il valore <head> del documento è lo stesso per ogni route (almeno al momento dell'elaborazione). Se aggiungi un hint preload a <head>, la risorsa verrà precaricata per tutte le route anche dove non è richiesta. Di conseguenza, l'aggiunta manuale di preload suggerimenti non è consigliata.

    Aggiunta automatica durante il rendering:utilizzare il 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 e l'esecuzione di JavaScript, il rendering dell'elemento <head> verrà eseguito troppo tardi per avere un valore qualsiasi.

    Per la prima versione dell'istruzione, viene utilizzata una combinazione di suggerimenti preconnect e fetchpriority suggerimenti per dare la priorità all'immagine al posto di preload. Tuttavia, al momento Aurora sta collaborando con il team dell'interfaccia a riga di comando Angular per abilitare l'inserimento automatico di suggerimenti sulle risorse in fase di creazione. Continua a seguirci!

  2. Ottimizzare le dimensioni e il 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 dimostra la differenza che può fare la direttiva Angular Image rispetto alle prestazioni 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).

Sito web due: utilizza l'istruzione 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 aspettavamo che il loro sito sarebbe stato un buon caso di test per ottenere risultati che le applicazioni reali avrebbero visto.

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

Roadmap futura

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

  • Supporto migliore per immagini reattive:

    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 sulle risorse

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

  • Supporto per SSR Angular

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

  • Miglioramenti dell'esperienza di sviluppo

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

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

Conclusione

La direttiva Angular Image sarà disponibile per gli sviluppatori in 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.