Novità dell'istruzione Angular NgOptimizedImage

Castello di Alex
Castello di Alex

Poco più di un anno fa, il team di Chrome Aurora ha lanciato l'istruzione Angular NgOptimizedImage. L'obiettivo principale della direttiva è migliorare le prestazioni, in base alla misurazione delle metriche Segnali web essenziali. Raggruppa le ottimizzazioni e le best practice più comuni delle immagini in un'API rivolta agli utenti che non è molto più complicata di un elemento <img> standard.

Nel 2023 abbiamo migliorato l'istruzione con nuove funzionalità. Questo post descrive le caratteristiche più importanti di queste nuove funzionalità, ponendo l'accento sul motivo per cui abbiamo scelto di dare la priorità a ciascuna funzionalità e su come può contribuire a migliorare le prestazioni delle applicazioni Angular.

Nuove funzionalità

NgOptimizedImage è migliorata notevolmente nel tempo, incluse le nuove funzionalità riportate di seguito.

Modalità riempimento

Ridimensionare le immagini fornendo un attributo width e height è un'ottimizzazione estremamente importante per ridurre la variazione del layout, perché i browser devono conoscere le proporzioni dell'immagine per fare in modo che possa lasciarne spazio. Tuttavia, le dimensioni delle immagini sono un lavoro aggiuntivo per gli sviluppatori di applicazioni e non ha senso con alcuni casi d'uso delle immagini.

La prima funzionalità principale aggiunta al componente immagine dopo l'anteprima per gli sviluppatori è la prima funzionalità principale che contribuisce a risolvere questa situazione: modalità riempimento. In questo modo gli sviluppatori possono includere immagini senza specificarne le dimensioni e senza incorrere in variazioni del layout.

Con la modalità di riempimento, il requisito di dimensioni delle immagini viene disattivato e all'immagine viene applicato automaticamente lo stile per riempire l'elemento contenitore. In questo modo le proporzioni dell'immagine vengono disaccoppiate dallo spazio che occupa sulla pagina e ti offre un maggiore controllo sul modo in cui le immagini si adattano al layout della pagina.

La modalità di riempimento utilizza NgOptimizedImage come alternativa con 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 sulla pagina <div> per controllare il posizionamento dell'immagine sullo 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 srcset

Una delle tecniche di ottimizzazione delle immagini più efficaci è l'utilizzo dell'attributo srcset per garantire che le immagini delle dimensioni corrette vengano scaricate per qualsiasi dispositivo che accede alla tua applicazione. L'utilizzo di srcset in tutta l'app può evitare di sprecare la larghezza di banda e migliorare sostanzialmente il tuo Segnale web essenziale LCP.

L'aspetto negativo dell'attributo srcset è che può essere difficile da implementare. Scrivere manualmente i valori srcset significa aggiungere più righe di markup a ogni elemento immagine dell'app, con tanto di URL personalizzati per ogni elemento srcset. Devi anche decidere un insieme di punti di interruzione, 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 all'istruzione NgOptimizedImage è stata un'importante pietra miliare dopo il lancio. Con questa aggiunta, qualsiasi applicazione che utilizza una CDN che supporta il ridimensionamento delle immagini può ottenere srcset completi e personalizzabili a ogni immagine generata con la direttiva NgOptimizedImage.

Abbiamo incluso un'API semplificata per impostare la proprietà sizes, che viene utilizzata per garantire che ogni immagine riceva il tipo corretto di srcset. Se non includi un attributo sizes, sappiamo che l'immagine ha dimensioni fisse e dovrebbe avere un 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 con dimensioni che tengano conto della densità in pixel del dispositivo dell'utente.

Se invece includi la proprietà sizes, NgOptimizedImage genera un srcset adattabile che includa i punti di interruzione per molte dimensioni comuni di dispositivi e immagini, utilizzando questo elenco predefinito di punti di interruzione:

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

Generazione preconnessione

Per migliorare il valore LCP, è importante ridurre il tempo impiegato dagli utenti per scaricare l'immagine LCP. Nella sezione precedente hai visto in che modo srcset può contribuire al trasferimento di 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 dell'immagine.

Fin dall'inizio, NgOptimizedImage ha inviato un avviso se non ti preconnetti al dominio dell'immagine LCP, ma l'avviso non è la soluzione ideale: vorremmo risolvere il problema al posto tuo. Ed è esattamente ciò che fa ora NgOptimizedImage, con la generazione automatica di preconnessione.

Per supportare questa funzionalità, utilizziamo l'analisi del codice statico per tentare di rilevare i domini delle immagini nei caricatori di NgOptimizedImage e generiamo automaticamente tag link di preconnessione per questi domini. Può capitare che i link di preconnessione manuali siano obbligatori. Tuttavia, per la maggior parte degli utenti, il precollegamento automatico comporta un passaggio in meno per ottenere un buon rendimento delle immagini.

Supporto migliorato per i caricatori personalizzati

Un elemento chiave di NgOptimizedImage è l'architettura di caricamento, che consente all'istruzione di generare automaticamente URL su misura per la rete CDN di immagini dell'applicazione. È incluso un set di caricatori integrati per le reti CDN di uso comune. Prevediamo inoltre l'utilizzo di caricatori personalizzati, che consentono di integrare NgOptimizedImage in quasi tutte le soluzioni 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 il trasferimento di dati arbitrari dall'elemento immagine al caricatore personalizzato. Con l'espansione, i caricatori personalizzati possono essere semplici o complessi, in base alle esigenze dell'infrastruttura di immagini di un'applicazione.

L'esempio seguente mostra in che modo un semplice caricatore personalizzato potrebbe utilizzare l'API loaderParams per scegliere tra due domini immagine 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 estese per le prestazioni delle immagini

Finora, tutti gli avvisi sulle prestazioni delle immagini che abbiamo aggiunto ad Angular facevano parte dell'istruzione NgOptimizedImage. Se non utilizzi l'istruzione nell'app, non riceverai indicazioni sui problemi di prestazioni delle immagini.

In Angular 17, stiamo estendendo l'ambito delle indicazioni sul rendimento delle immagini per includere tutte le app Angular. Ora, se rileviamo pattern di immagini che compromettono gli errori in termini di prestazioni, come il caricamento lento dell'immagine LCP o il download di un file troppo grande per la pagina, te lo comunicheremo, anche se non stai utilizzando NgOptimizedImage.

Le prestazioni delle immagini sono importanti per tutte le app e siamo entusiasti di continuare a creare misure di protezione per aiutare a prevenire gli errori comuni nelle app Angular.

Prospettive future

Stiamo già lavorando sodo per sviluppare il prossimo insieme di funzionalità per NgOptimizedImage. Anche se le prestazioni delle immagini rimangono la nostra principale preoccupazione, vorremmo anche aggiungere funzionalità che migliorano l'esperienza degli sviluppatori, per assicurarci che NgOptimizedImage rimanga un'opzione allettante per l'inclusione delle immagini nelle applicazioni Angular.

Una delle nostre priorità sono i segnaposto delle immagini. Questi vengono comunemente utilizzati per migliorare il caricamento delle immagini nelle applicazioni web, ma possono compromettere le prestazioni se implementate in modo errato. Ci auguriamo di poter sviluppare in NgOptimizedImage un sistema di segnaposto per immagini che metta in evidenza il rendimento. Segui il nostro blog per ulteriori annunci.