Image optimization in Angular | Aulab
TECH SUMMER LAB 🚀 Open Month
| 6 lezioni gratuite per orientarti al meglio e iniziare a costruire il tuo futuro digitale! Iscriviti gratis

GUIDE PER ASPIRANTI PROGRAMMATORI

Image optimization in Angular

Con le deferrable views, abbiamo visto come ottimizzare i tempi iniziali di caricamento, riducendo le dimensioni del bundle scaricato inizialmente, e caricando i componenti secondari in un secondo momento. Con questo tipo di ragionamento, il parametro che si va ad ottimizzare è il tempo di caricamento del minimo indispensabile affinché l’utente possa iniziare a interagire…

Lezione 17 / 17
Enza Neri
Immagine di copertina

Vuoi avviare una nuova carriera o fare un upgrade?

Trova il corso Digital & Tech più adatto a te nel nostro catalogo!

Con le deferrable views, abbiamo visto come ottimizzare i tempi iniziali di caricamento, riducendo le dimensioni del bundle scaricato inizialmente, e caricando i componenti secondari in un secondo momento.

Con questo tipo di ragionamento, il parametro che si va ad ottimizzare è il tempo di caricamento del minimo indispensabile affinché l’utente possa iniziare a interagire con l’app; questo parametro è anche chiamato First contentful paint (FCP, che potremmo tradurre un po’ infedelmente come prima presentazione di contenuto).

Un altro parametro importante che si misura solitamente è il Largest contentful paint (LCP, cioè la più grande presentazione di contenuto), che va a misurare il tempo impiegato per mostrare completamente il più grande blocco di contenuto della pagina.

Chiaramente, i tempi di caricamento di un’immagine sono più lunghi di quelli di un testo, a parità di spazio occupato; per questa ragione, nel tempo si è sviluppata tutta una serie di pratiche per ottimizzare il caricamento delle immagini.

Ora, dato che uno dei propositi (nonché un grande punto di forza) di Angular è la completezza, non poteva mancare un’API del framework per affrontare la questione. Questa API è implementata attraverso la direttiva NgOptimizedImage, esportata dal modulo @angular/common; in questa sezione vediamo come usarla.


Trattandosi di una normalissima direttiva attributo, la base del suo funzionamento consiste nell’includerla tra gli imports del componente e attivarla usando l’attributo ngSrc al posto di src su un tag img:

<img ngSrc="https://picsum.photos/200/300">

In questo esempio usiamo Lorem Picsum come libreria di immagini a titolo esemplificativo. Come vedremo, alcune API sono specificamente dedicate a servizi CDN che si occupano più specificamente di image optimization.

Se proviamo a lanciare la web app, noteremo che in console compare un errore: questo ci dice che dobbiamo necessariamente impostare gli attributi height e width, oppure usare fill. Questo obbligo serve ad aiutare la direttiva a riservare correttamente lo spazio per l’immagine durante il caricamento, per evitare stravolgimenti del layout quando l’utente ha già iniziato a interagire con l’interfaccia grafica.

Quindi il nostro esempio diventa:

<img ngSrc="https://picsum.photos/200/300" height="200" width="300">

Per quanto riguarda, invece, l’uso di fill, questo attributo serve nel caso in cui vogliamo che le dimensioni dell’immagine siano ricavate dal suo contenitore, che dovrà necessariamente avere una posizione CSS uguale a relative, fixed o absolute.

Sarà possibile decidere come collocare l’immagine all’interno dello spazio disponibile stilizzando il tag img con la proprietà CSS object-fit impostata su contain o cover.-

L’uso di fill ci consente di utilizzare di fare image optimization anche laddove l’immagine ha semplicemente lo scopo di fare da sfondo a un elemento.


Per ottimizzare il tempo di caricamento dell’immagine più grande, e dunque migliorare il parametro LCP, possiamo usare l’attributo priority sull’immagine o sulle immagini più grandi.

<img ngSrc="https://picsum.photos/200/300" width="200" height="300" priority>

A questo punto, Angular fornirà un warning, suggerendoci di aggiungere il seguente tag nella <head> di index.html:

<link rel="preconnect" href="https://picsum.photos">

Questo è dovuto al fatto che parte delle logiche applicate da NgOptimizedImage per migliorare l’esperienza di caricamento delle immagini dipende dal concetto di loader, cioè una funzione che modifica l’url dell’immagine con parametri in grado di adattare la sua dimensione o risoluzione.
Il concetto di loader è a sua volta legato al funzionamento delle content delivery networks (CDN) che si occupano di hostare immagini e prevedono parametri con i quali manipolare l’immagine in modo da adeguarne la dimensione e la qualità all’esigenza effettiva.

Angular fornisce dei loader built-in per alcuni servizi CDN come Netlify o Cloudflare, ed è anche possibile fornire un custom loader per un altro servizio non supportato. Poiché NgOptimizedImage assume che tutte le immagini provengano da una singola CDN, è necessario implementare un custom loader nel caso in cui la nostra web app ne usi più di una.

Ebbene, tornando al preconnect, il warning di prima deriva proprio dal fatto che Angular non ha riconosciuto alcun loader per https://picsum.photos. In questa guida non ci occuperemo di interagire con alcun servizio CDN in particolare, ma vedremo comunque alcune ottimizzazioni supportate da NgOptimizedImage e basate sull’uso delle CDN e dei loader.

Una di queste è l’attributo placeholder, che scaricherà una seconda immagine a risoluzione più bassa, da mostrare mentre quella più grande viene caricata:

<img ngSrc="https://picsum.photos/200/300" width="200" height="300" placeholder>

Come placeholder è anche possibile usare un data-URL in base64 contenente l’immagine segnaposto:

<img ngSrc="https://picsum.photos/200/300" width="200" height="300" placeholder="data:image/png;base64,<base64_string>">

Fin qui abbiamo visto le API di ottimizzazione più comuni ed espresso i concetti principali legati alla direttiva NgOptimizedImage; volendo approfondire ulteriormente, dovremmo addentrarci nei seguenti argomenti:

  • dimensioni dell’immagine dinamiche in base al dispositivo (attraverso l’impostazione degli attributi srcset e sizes),
  • implementazione di loader custom.

Tuttavia, questi argomenti sono densi di tecnicismi legati alla responsiveness dei contenuti e all’interazione con le CDN, ed esulano dallo scopo di questa guida.

Hai bisogno di informazioni? 🙋🏻‍♂️

Parliamone! Scrivici su Whatsapp e risponderemo a tutte le tue domande per capire quale dei nostri corsi è il più adatto alle tue esigenze.

Oppure chiamaci al 800 128 626