Novità dell'istruzione Angular NgOptimizedImage

Alex Castle
Alex Castle

Poco più di un anno fa, il team di Chrome Aurora ha lanciato la direttiva NgOptimizedImage di Angular. La direttiva si concentra principalmente sul miglioramento del rendimento, misurato dalle metriche Core Web Vitals. Raggruppa le ottimizzazioni e le best practice comuni per le immagini in un'API rivolta agli utenti non molto più complicata di un elemento <img> standard.

Nel 2023 abbiamo migliorato la direttiva con nuove funzionalità. Questo post descrive le più importanti di queste nuove funzionalità, mettendo in evidenza il motivo per cui abbiamo scelto di dare la priorità a ciascuna e in che modo può contribuire a migliorare il rendimento delle applicazioni Angular.

Nuove funzionalità

NgOptimizedImage è migliorato notevolmente nel tempo, includendo le seguenti nuove funzionalità.

Modalità di riempimento

Il ridimensionamento delle immagini mediante l'attributo width e height è un'ottimizzazione estremamente importante per ridurre il cambio di layout, perché i browser devono conoscere le proporzioni dell'immagine per riservarle spazio. Tuttavia, la regolazione delle dimensioni delle immagini comporta un lavoro aggiuntivo per gli sviluppatori di applicazioni e non ha senso per alcuni casi d'uso delle immagini.

A risolvere questo problema contribuisce la prima funzionalità principale aggiunta al componente immagine dopo l'anteprima per sviluppatori: la modalità di riempimento. In questo modo, gli sviluppatori possono includere le immagini senza specificarne esplicitamente le dimensioni e senza che si verifichi uno spostamento del layout.

Con la modalità di riempimento, il requisito relativo alle dimensioni delle immagini viene disattivato e l'immagine viene stilizzata automaticamente per riempire l'elemento contenitore. In questo modo, le proporzioni di un'immagine vengono disaccoppiate dallo spazio che occupa nella pagina e hai un maggiore controllo su come le immagini si inseriscono nel layout della pagina.

La modalità di riempimento utilizza NgOptimizedImage come alternativa con un rendimento migliore alla proprietà CSS background-image. Inserisci un'immagine all'interno di <div> o di un altro elemento che avrebbe avuto lo stile background-image, quindi attiva la modalità di riempimento, come mostrato nell'esempio di codice precedente. Utilizza le proprietà CSS object-fit e object-position in <div> per controllare la posizione dell'immagine nello sfondo.

// Height and width are required
<img ngSrc="example.com" height="300" width="400">

// Unless you use fill mode!
<div style="width: 100vw; height: 50em; position: relative">
  <img ngSrc="example.com" fill>
</div>

Generazione di srcset

Una delle tecniche di ottimizzazione delle immagini più efficaci è l'utilizzo dell'attributo srcset per assicurarsi che vengano scaricate immagini con dimensioni adeguate per qualsiasi dispositivo che accede alla tua applicazione. L'utilizzo di srcset in tutta l'app può impedirti di sprecare larghezza di banda e migliorare notevolmente il LCP Core Web Vital.

Lo svantaggio dell'attributo srcset è che può essere complicato da implementare. La scrittura manuale dei valori srcset comporta l'aggiunta di più righe di markup a ogni elemento immagine dell'app, con più URL personalizzati per ogni srcset. Devi anche decidere un insieme di breakpoint, il che è complicato, in quanto possono rappresentare sia le densità dello schermo sia le dimensioni dell'area visibile dei dispositivi comuni.

Ecco perché l'aggiunta della generazione automatica di srcset alla direttiva NgOptimizedImage è stata un traguardo importante dopo il lancio. Con questa aggiunta, qualsiasi applicazione che utilizza una CDN che supporta il ridimensionamento delle immagini può avere srcset completi e personalizzabili aggiunti automaticamente a ogni immagine generata con la direttiva NgOptimizedImage.

Abbiamo incluso un'API semplificata per l'impostazione della proprietà sizes, che viene utilizzata per assicurarsi che a ogni immagine venga assegnato il tipo corretto di sizes.srcset Se non includi un attributo sizes, sappiamo che l'immagine deve avere dimensioni fisse e deve avere un attributo srcset dipendente dalla densità, come il seguente:

<img src="www.example.com/image.png" srcset="www.example.com/image.png?w=400 1x, www.example.com/image.png?w=800 2x" >

Questo tipo di srcset garantisce che le immagini vengano pubblicate in dimensioni che tengano conto della densità di pixel del dispositivo dell'utente.

Se invece includi la proprietà sizes, NgOptimizedImage genera un attributo srcset responsive che include i breakpoint per molti dispositivi e dimensioni delle immagini comuni, utilizzando questo elenco predefinito di breakpoint:

[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]

Generazione di preconnect

Per migliorare il valore di questa metrica, è importante ridurre il tempo impiegato dagli utenti per scaricare l'immagine LCP. Nella sezione precedente hai visto come srcset può aiutarti trasferendo file immagine più piccoli, ma un'ottimizzazione altrettanto importante è avviare il trasferimento il prima possibile. Un modo per farlo è utilizzare i tag link rel="preconnect" per avviare la connessione al dominio delle immagini.

Fin dall'inizio, NgOptimizedImage ha emesso un avviso se non riesci a eseguire la preconnessione al dominio dell'immagine LCP, ma l'avviso non è la soluzione ideale: preferiamo risolvere il problema per te. Ed è esattamente ciò che fa ora NgOptimizedImage, con la generazione automatica di preconnect.

Per supportare questa funzionalità, utilizziamo l'analisi statica del codice per tentare di rilevare i domini delle immagini nei caricatori NgOptimizedImage e generare automaticamente i tag link preconnect per questi domini. Potrebbero comunque esserci casi in cui sono necessari link di preconnessione manuali, ma per la maggior parte degli utenti, la preconnessione automatica significa un passaggio in meno necessario per ottenere un buon rendimento delle immagini.

Supporto migliorato per i caricatori personalizzati

Un elemento chiave di NgOptimizedImage è l'architettura del caricatore, che consente alla direttiva di generare automaticamente URL personalizzati per la CDN di immagini dell'applicazione. È incluso un insieme di caricatori integrati per le CDN di uso comune. Forniamo inoltre l'utilizzo di caricatori personalizzati, che ti consentono di integrare NgOptimizedImage con quasi qualsiasi soluzione di hosting di immagini.

Al momento del lancio, questi caricatori personalizzati avevano un ambito limitato e potevano leggere solo l'attributo width dall'elemento immagine. In risposta al feedback degli utenti, abbiamo aggiunto il supporto di una struttura di dati loaderParams personalizzabile, che consente di passare dati arbitrari dall'elemento immagine al caricatore personalizzato. Con l'espansione, i caricatori personalizzati possono essere semplici o complessi, a seconda delle esigenze dell'infrastruttura di immagini di un'applicazione.

L'esempio seguente mostra come un semplice caricatore personalizzato potrebbe utilizzare l'API loaderParams per scegliere tra due domini di immagini alternativi:

const myCustomLoader = (config: ImageLoaderConfig) => {
  if (config.loaderParams?.alternateDomain) {
    return `https://alternate.domain.com/images/${config.src}`
  }
  return `https://primary.domain.com/images/${config.src}`;
};

Un esempio di caricatore personalizzato più complesso è disponibile nella documentazione di Angular.

Indicazioni più dettagliate sul rendimento delle immagini

Fino a questo momento, tutti gli avvisi sul rendimento delle immagini che abbiamo aggiunto ad Angular facevano parte della direttiva NgOptimizedImage. Se non utilizzi la direttiva nell'app, non riceverai indicazioni sui problemi di prestazioni delle immagini.

In Angular 17, stiamo ampliando l'ambito delle indicazioni sul rendimento delle immagini per includere tutte le app Angular. Ora, se rileviamo pattern di immagini che sappiamo essere errori che influiscono sulle prestazioni, ad esempio il caricamento lento dell'immagine LCP o il download di un file troppo grande per la pagina, te lo comunicheremo, anche se non utilizzi NgOptimizedImage.

Il rendimento delle immagini è importante per tutte le app e siamo lieti di continuare a creare linee guida per contribuire a evitare errori comuni nelle app Angular.

Cordiali saluti

Stiamo già lavorando per sviluppare il prossimo insieme di funzionalità per NgOptimizedImage. Sebbene le prestazioni delle immagini rimangano la nostra preoccupazione principale, vorremmo anche aggiungere funzionalità che migliorino l'esperienza degli sviluppatori, per assicurarci che NgOptimizedImage rimanga un'opzione interessante per includere le immagini nelle applicazioni Angular.

Una funzionalità che per noi è una priorità è rappresentata dai segnaposto per le immagini. Questi vengono spesso utilizzati per migliorare la visualizzazione del caricamento delle immagini nelle applicazioni web, ma possono influire negativamente sul rendimento se implementati in modo errato. Ci auguriamo di creare un sistema di segnaposto delle immagini incentrato sulle prestazioni in NgOptimizedImage. Continua a seguirci sul nostro blog per altri annunci.