Ottimizzazione delle immagini con la direttiva Angular Image

Chiara Strada
Kara Erickson
Leena Sohoni
Leena Sohoni

A maggio 2022, i team di Aurora e Angular hanno annunciato che avrebbero collaborato a una direttiva sulle immagini per Angular. La direttiva è stata rilasciata di recente per l'anteprima per gli sviluppatori nell'ambito della versione 14.2 di Angular. Questo post spiega come la nuova istruzione relativa alle immagini, NgOptimizedImage, supporta 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, costituendo una media di 982 kilobyte per pagina.

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

Il team di Aurora crede nella necessità di sfruttare la potenza dei framework per fornire soluzioni integrate alle sfide più comuni degli sviluppatori. La loro prima esperienza nello spazio di ottimizzazione delle immagini è stata il componente immagine Next.js. Hanno 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 migliori in termini di prestazioni per più app che utilizzano framework.

Il primo set di risultati dell'utente di Next.js Leboncoin era 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 contribuito all'aumento delle origini Next.js che rispettano le soglie di LCP. Presto sono state generate richieste per funzionalità simili in altri framework, di cui uno di tipo Angular.

Di conseguenza, Aurora si è consultata con Angular e Nuxt per prototipare i componenti di immagine per questi framework. Il componente immagine Nuuxt è stato rilasciato l'anno scorso. Ora l'istruzione Angular image (NgOptimizedImage) è stata rilasciata per impostare le impostazioni predefinite per l'ottimizzazione delle immagini su Angular.

Opportunity

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

LCP per i siti web di Angular nell'ultimo anno.

Osservando i punteggi dei Segnali web essenziali, la percentuale di origini Angular che soddisfano le soglie LCP "buone" deve ancora lavorare. A giugno 2022, solo il 18,74% dei siti di Angular presentava un buon LCP sui 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 valore LCP più scarso sui siti web Angular.

L'istruzione Angular image è stata pensata per contribuire a migliorare questi valori.

MVP per l'istruzione NgOptimizedImage

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

  • Fornire valori predefiniti efficaci.
  • Generazione di errori o avvisi per garantire la conformità alle best practice.

I punti salienti del design sono i seguenti:

  1. Caricamento lento intelligente

    Le immagini che non sono visibili all'utente al caricamento della pagina (ad esempio, immagini below the fold o immagini carosello nascoste) dovrebbero essere caricate lentamente. Il caricamento lento libera le risorse del browser in modo da caricare altri testi, contenuti multimediali o script di importanza critica. La maggior parte delle immagini non è critica e dovrebbe essere caricata tramite caricamento lento, ma nel 2021 solo il 7,8% delle pagine ha utilizzato il caricamento lento nativo.

    L'istruzione Angular image carica le immagini non critiche per impostazione predefinita e carica con entusiasmo solo le immagini contrassegnate in modo specifico come priority. Ciò garantisce che la maggior parte delle immagini mostri un comportamento di caricamento ottimale.

  2. Assegnazione della priorità alle immagini critiche

    Aggiungere hint sulle 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 li utilizza. Secondo l'Almanacco web 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 image agisce su due fronti quando le immagini sono contrassegnate come priorità.

    • Imposta il valore fetchPriority dell'immagine su "high" per indicare al browser 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à sviluppo, l'istruzione utilizza anche l'API PerformanceObservationr per verificare che l'immagine LCP sia stata contrassegnata come priority come previsto. Se non è contrassegnato come priority, viene generato un errore che chiede 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 per l'attributo fetchpriority pari a high e che non venga eseguito un caricamento lento.

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

    Ti consigliamo di utilizzare CDN di immagini per le applicazioni Angular, che spesso forniscono servizi di ottimizzazione per impostazione predefinita.

    La direttiva incoraggia l'utilizzo di CDN di immagini, offrendo agli sviluppatori un'esperienza particolarmente interessante per configurarle nell'app. Supporta un'API di caricamento che consente di definire il provider CDN e l'URL di base nella configurazione. Dopo la configurazione, devi definire solo 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 immagine fornisce i caricatori integrati con una configurazione ottimale per le CDN immagine più diffuse. Questi caricatori formattano automaticamente gli URL delle immagini per garantire che per ogni CDN vengano utilizzate le impostazioni di compressione e il formato delle immagini consigliate.

  4. Errori e avvisi integrati

    Oltre alle ottimizzazioni integrate sopra riportate, l'istruzione ha anche dei controlli integrati per garantire che gli sviluppatori abbiano seguito le best practice consigliate per il markup delle immagini. L'istruzione image esegue i seguenti controlli.

    1. Immagini senza dimensioni: l'istruzione relativa alle immagini genera un errore se nel markup dell'immagine non sono state definite larghezza e altezza esplicite. Le immagini senza dimensioni possono causare variazioni del layout che incidono sulla metrica Cumulative Layout Shift (CLS) della pagina. La best practice consigliata per evitare che ciò accada è che per le immagini è necessario specificare gli attributi width e height.

    2. Proporzioni:l'istruzione relativa alle immagini genera un errore per comunicare agli sviluppatori se le proporzioni di width:height definite nel codice HTML non sono simili alle proporzioni effettive dell'immagine visualizzata. Di conseguenza, 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 tuo CSS hai definito una dimensione in base alla percentuale, ma non l'altra (ad esempio, width: 100% deve avere height: auto per garantire che l'immagine cresca in entrambe le dimensioni).
    3. Immagini di grandi dimensioni: se l'immagine non definisce un srcset e l'immagine intrinseca è molto più grande dell'immagine visualizzata, l'istruzione mostrerà un avviso che suggerisce l'uso degli attributi srcset e sizes.

    4. Densità immagine:l'istruzione genererà un errore se tenti di includere un'immagine in srcset con una densità dei pixel superiore a 3x. In genere si sconsigliano descrizioni superiori a 2x perché hanno la conseguenza involontaria di forzare il download di immagini di grandi dimensioni sui dispositivi mobili ad alta risoluzione. Inoltre, l'occhio umano non è in grado di rilevare molta differenza oltre 2x.

sfide

Adattare le strategie di ottimizzazione delle immagini in modo che funzionino all'interno di un framework lato client è stata una sfida principale durante la 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 (circa il 60%) utilizza la funzionalità CSR.

La direttiva sull'immagine è interamente creata per consentire alla CSR di allinearsi al caso d'uso tipico delle app Angular. Questo ha posto dei vincoli aggiuntivi e il team ha dovuto ripensare a come sviluppare ottimizzazioni specifiche per le app di CSR.

Di seguito sono riportate alcune delle sfide riscontrate:

  1. Suggerimenti relativi alle risorse di supporto

    Il precaricamento degli asset critici consente al browser di individuarli prima. Tuttavia, includere i suggerimenti sulle risorse nelle app Angular è complicato perché:

    Aggiunta manuale: per gli sviluppatori è difficile aggiungere manualmente il suggerimento sulle risorse preload. Angular utilizza un file index.html condiviso per l'intero progetto o per tutti i percorsi sul sito web. Di conseguenza, il valore <head> del documento è uguale per ogni percorso (almeno al momento della pubblicazione). Se aggiungi un suggerimento preload a <head>, la risorsa verrà precaricata per tutte le route, anche dove non è richiesta. Pertanto, l'aggiunta manuale di preload suggerimenti 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 risolve il problema. Poiché il rendering si verifica dopo il download e l'esecuzione di JavaScript, <head> verrà mostrato troppo tardi per avere qualsiasi valore.

    Per la prima versione dell'istruzione, viene utilizzata una combinazione di suggerimenti preconnect e fetchpriority per assegnare la priorità all'immagine anziché preload. Tuttavia, Aurora sta attualmente collaborando con il team dell'interfaccia a riga di comando di Angular per abilitare l'inserimento automatico dei suggerimenti delle risorse in fase di creazione. Resta sintonizzato!

  2. Ottimizzare le dimensioni e il formato delle immagini sul server

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

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

Impatto

La demo seguente mostra la differenza che la direttiva Angular può apportare alle prestazioni delle immagini. Confronta due siti web:

Website One: utilizza elementi <img> nativi con immagini pubblicate tramite CDN Imgix (con opzioni di configurazione predefinite).

Sito web 2: utilizza la direttiva immagine per tutte le immagini. Sono incluse anche le ottimizzazioni consigliate direttamente dagli avvisi o dagli errori generati dall'istruzione.

Confronto tra la sequenza: il sito web uno con tag immagine nativi rispetto al sito web due con la direttiva Angular image.

Il team ha collaborato con i partner per convalidare l'impatto sulle prestazioni della direttiva sull'immagine sulle applicazioni Angular reali dell'azienda.

Uno di questi partner era Land's End. Ci aspettavamo che il sito dell'azienda sarebbe stato un buon scenario di test per ottenere risultati che le applicazioni reali potevano avere.

I test di laboratorio di Lighthouse sono stati eseguiti nell'ambiente di QA prima e dopo l'utilizzo della direttiva sulle immagini. Sui computer, la LCP mediana è scesa da 12,0 a 3,0 secondi, un miglioramento del 75% della metrica LCP. Sui dispositivi mobili, la LCP mediana è scesa da 20,2 a 12,0 secondi (miglioramento del 40,6%).

Roadmap futuro

Questa è solo la prima parte del design dell'istruzione Angular image. Sono previste molte altre funzionalità per le versioni future, tra cui:

  • Supporto migliore per le immagini adattabili:

    NgOptimizedImage attualmente supporta l'uso 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 dei suggerimenti delle risorse

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

  • Supporto per Angular SSR

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

  • Miglioramenti dell'esperienza degli sviluppatori

    NgOptimizedImage richiede che vengano specificati gli attributi width e height per ogni immagine. Tuttavia, specificare questi valori per ogni immagine può essere noioso per alcuni sviluppatori. Nella prossima iterazione, esiste un potenziale per migliorare l'esperienza degli sviluppatori, come indicato di seguito:

    1. Supportare una modalità aggiuntiva (simile all'opzione di layout immagine"fill" in Next.js) che non richiede la definizione di larghezza/altezza esplicite.
    2. Utilizzare l'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 sulle immagini sarà disponibile per gli sviluppatori in fasi, a partire dalla versione di anteprima per gli sviluppatori nella v14.2.0. Prova NgOptimizedImage e lascia un feedback.

Grazie speciali a Katie Hempenius e Alex Castle per il loro contributo.