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.
Sfondo
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.
Opportunità
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.
Osservando i punteggi Core Web Vitals, la percentuale di origini Angular che soddisfano i criteri Le soglie LCP richiedono ancora interventi da parte tua. 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:
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.Assegnazione della priorità alle immagini più importanti
Aggiungi hint delle risorse (ad es.
preload
opreconnect
) 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 comepriority
, viene generato un errore che indica allo sviluppatore di aggiungere l'attributopriority
all'immagine LCP.In definitiva, questa combinazione di automazione e conformità garantisce che l'immagine LCP abbia un suggerimento
preconnect
, un valore dell'attributofetchpriority
pari ahigh
e che non venga caricato tramite caricamento lento.- Viene impostata la priorità di recupero dell'immagine su
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 sviluppatore (DX) particolarmente interessante 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.
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.
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
eheight
per le immagini.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- Hai definito le dimensioni errate (larghezza o altezza) per errore o
- Se nel CSS hai definito una dimensione in base alla percentuale, ma non l'altra (ad esempio,
width: 100%
ha bisogno diheight: auto
per garantire che l'immagine aumenti in entrambe le dimensioni).
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 attributisrcset
esizes
.Densità immagine: l'istruzione genera un errore se tenti di includere un'immagine nell'elemento
srcset
con una densità di pixel superiore a3x
. I descrittori superiori a2x
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:
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 hintpreload
a<head>
, la risorsa verrà precaricata per tutte le route anche dove non è richiesta. Di conseguenza, l'aggiunta manuale dipreload
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
efetchpriority
suggerimenti per dare la priorità all'immagine al posto dipreload
. 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!Ottimizzare le dimensioni e il formato delle immagini sul server
Poiché in genere le app Angular vengono 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, è 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.
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 disrcset
, ma gli attributisrcset
esizes
devono essere forniti manualmente per ogni immagine. In futuro, l'istruzione potrebbe generare automaticamente gli attributisrcset
esizes
.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 attributiwidth
eheight
. Tuttavia, specificarli per ogni immagine può essere faticoso per alcuni sviluppatori. Ecco le potenzialità di miglioramento dell'esperienza degli sviluppatori nella prossima iterazione:- Supportare una modalità aggiuntiva (simile all'opzione di layout dell'immagine in Next.js "
fill
") che non richiede la definizione di larghezza/altezza esplicite. - 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.
- Supportare una modalità aggiuntiva (simile all'opzione di layout dell'immagine in Next.js "
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.