Le immagini sono spesso la risorsa più pesante e più diffusa sul web. Di conseguenza, l'ottimizzazione delle immagini può migliorare notevolmente il rendimento del tuo sito web. Nella maggior parte dei casi, ottimizzare le immagini significa ridurre il tempo di rete inviando meno byte, ma puoi anche ottimizzare la quantità di byte inviati all'utente pubblicando immagini con dimensioni adeguate al dispositivo dell'utente.
Le immagini possono essere aggiunte a una pagina utilizzando gli elementi <img>
o <picture>
o la proprietà background-image
CSS.
Image size
La prima ottimizzazione che puoi eseguire quando utilizzi le risorse immagine è visualizzare l'immagine nelle dimensioni corrette; in questo caso, il termine size si riferisce alle dimensioni di un'immagine. Senza considerare altre variabili, un'immagine visualizzata in un container di 500 x 500 pixel avrà dimensioni ottimali di 500 x 500 pixel. Ad esempio, se utilizzi un'immagine quadrata da 1000 pixel, l'immagine è il doppio delle dimensioni necessarie.
Tuttavia, sono molte le variabili coinvolte nella scelta della dimensione giusta delle immagini, il che rende piuttosto complicata l'operazione di scelta della dimensione giusta dell'immagine in ogni caso. Nel 2010, quando è stato lanciato l'iPhone 4, la risoluzione dello schermo (640 x 960) era il doppio di quella dell'iPhone 3 (320 x 480). Tuttavia, le dimensioni fisiche dello schermo dell'iPhone 4 sono rimaste all'incirca le stesse dell'iPhone 3.
Mostrare tutto a una risoluzione più alta avrebbe ridotto in modo significativo il testo e le immagini, pari a metà delle dimensioni precedenti. Invece, 1 pixel è diventato 2 pixel del dispositivo. Questo valore è chiamato rapporto di pixel del dispositivo (DPR). L'iPhone 4, e molti modelli di iPhone pubblicati successivamente, avevano un DPR pari a 2.
Riesaminando l'esempio precedente, se il dispositivo ha una DPR pari a 2 e l'immagine viene visualizzata in un container di 500 x 500 pixel, la dimensione ottimale è un'immagine quadrata da 1000 pixel (detta dimensioni intrinseche). Analogamente, se il dispositivo ha un DPR pari a 3, la dimensione ottimale è un'immagine quadrata da 1500 pixel.
srcset
L'elemento <img>
supporta l'attributo srcset
, che consente di specificare un
elenco di possibili origini delle immagini che il browser potrebbe utilizzare. Ogni origine immagine specificata deve includere l'URL dell'immagine e un descrittore di larghezza o di densità di pixel.
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
srcset="/image-500.jpg 1x, /image-1000.jpg 2x, /image-1500.jpg 3x"
>
Lo snippet HTML precedente utilizza il descrittore della densità dei pixel per suggerire al browser di utilizzare image-500.png
sui dispositivi con un DPR pari a 1, image-1000.jpg
sui dispositivi con DPR pari a 2 e image-1500.jpg
sui dispositivi con DPR pari a 3.
Anche se tutto questo può sembrare tagliato e secco, il DPR di uno schermo non è l'unica considerazione per la scelta dell'immagine ottimale per una determinata pagina. Il layout della pagina è un'altra considerazione.
sizes
La soluzione precedente funziona solo se visualizzi l'immagine con le stesse dimensioni in pixel CSS in tutte le aree visibili. In molti casi, il layout di una pagina e le dimensioni del contenitore cambiano in base al dispositivo dell'utente.
L'attributo sizes
consente di specificare un insieme di dimensioni delle origini, in cui ogni dimensione è costituita da una condizione dei contenuti multimediali e da un valore. L'attributo sizes
descrive le dimensioni di visualizzazione previste dell'immagine in pixel CSS. Se combinato con i descrittori di larghezza srcset
, il browser può scegliere l'origine dell'immagine migliore per il dispositivo dell'utente.
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
srcset="/image-500.jpg 500w, /image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
Nello snippet HTML precedente, l'attributo srcset
specifica un elenco di candidati immagine che il browser può scegliere, separati da virgole. Ogni candidato nell'elenco è costituito dall'URL dell'immagine, seguito da una sintassi che indica la larghezza intrinseca dell'immagine. Le dimensioni intrinseche di un'immagine sono le sue dimensioni. Ad esempio, il descrittore 1000w
indica che la larghezza intrinseca dell'immagine è di 1000 pixel.
Utilizzando queste informazioni, il browser valuta la condizione del supporto nell'attributo sizes
e, in questo caso, viene indicato che se la larghezza dell'area visibile del dispositivo supera i 768 pixel, l'immagine viene visualizzata con una larghezza di 500 pixel. Sui dispositivi più piccoli, l'immagine viene visualizzata nel punto 100vw
o nella larghezza intera dell'area visibile.
Il browser può quindi combinare queste informazioni con l'elenco di origini di immagini srcset
per trovare l'immagine ottimale. Ad esempio, se l'utente usa un dispositivo mobile con una larghezza dello schermo di 320 pixel e un DPR pari a 3, l'immagine viene visualizzata su 320 CSS pixels x 3 DPR = 960 device pixels
. In questo esempio, l'immagine delle dimensioni più vicine è image-1000.jpg
, che ha una larghezza intrinseca di 1000 pixel (1000w
).
Formati file
I browser supportano diversi formati di file immagine. I formati delle immagini moderni come WebP e AVIF possono fornire una compressione migliore rispetto ai formati PNG o JPEG, riducendo le dimensioni del file immagine e riducendo così i tempi di download. Pubblicando immagini in formati moderni, puoi ridurre il tempo di caricamento di una risorsa, il che potrebbe comportare una riduzione della metrica Largest Contentful Paint (LCP).
WebP è un formato ampiamente supportato che funziona su tutti i browser moderni. WebP spesso offre una compressione migliore rispetto a JPEG, PNG o GIF, offrendo sia la compressione con perdita di dati sia senza perdita di dati. WebP supporta inoltre la trasparenza del canale alfa anche in caso di compressione con perdita di dati, una funzione non offerta dal codec JPEG.
AVIF è un formato di immagine più recente e, sebbene non sia ampiamente supportato come WebP, offre un supporto ragionevolmente soddisfacente in tutti i browser. AVIF supporta sia la compressione con perdita di dati che quella senza perdita di dati e i test hanno dimostrato un risparmio superiore al 50% rispetto al formato JPEG in alcuni casi. AVIF offre anche le funzionalità Wide Color Gamut (WCG) e High Dynamic Range (HDR).
Compressione
Per quanto riguarda le immagini, esistono due tipi di compressione:
La compressione con perdita di dati riduce l'accuratezza dell'immagine attraverso la quantizzazione ed è possibile eliminare ulteriori informazioni sul colore utilizzando il sottocampionamento della crominanza. La compressione con perdita di dati è più efficace su immagini ad alta densità con molto rumore e colori, in genere foto o immagini con contenuti simili. Questo perché gli artefatti prodotti dalla compressione con perdita di dati hanno molto meno probabilità di essere notati in immagini così dettagliate. Tuttavia, la compressione con perdita di dati potrebbe essere meno efficace se si utilizzano immagini contenenti bordi nitidi come elementi grafici, dettagli altrettanto netti o testo. La compressione con perdita di dati può essere applicata a immagini JPEG, WebP e AVIF.
La compressione senza perdita di dati riduce le dimensioni del file comprimendo un'immagine senza perdita di dati. La compressione senza perdita di dati descrive un pixel in base alla differenza rispetto ai pixel vicini. La compressione senza perdita di dati viene utilizzata per i formati delle immagini GIF, PNG, WebP e AVIF.
Puoi comprimere le immagini utilizzando Squoosh, ImageOptim o un servizio di ottimizzazione delle immagini. Durante la compressione non esiste un'impostazione universale adatta a tutti i casi. L'approccio consigliato è sperimentare con diversi livelli di compressione fino a trovare un buon compromesso tra qualità delle immagini e dimensioni del file. Alcuni servizi avanzati di ottimizzazione delle immagini possono eseguire questa operazione automaticamente, ma potrebbero non essere finanziariamente attuabili per tutti gli utenti.
Elemento <picture>
L'elemento <picture>
offre una maggiore flessibilità nel specificare più
immagini candidati:
<picture>
<source type="image/avif" srcset="image.avif">
<source type="image/webp" srcset="image.webp">
<img
alt="An image"
width="500"
height="500"
src="/image.jpg"
>
</picture>
Quando utilizzi gli elementi <source>
all'interno dell'elemento <picture>
, puoi aggiungere il supporto per le immagini AVIF e WebP, ma tornare a formati di immagine precedenti più compatibili se il browser non supporta i formati moderni. Con questo approccio, il browser sceglie il primo elemento <source>
specificato corrispondente. Se riesce a visualizzare l'immagine in quel formato, viene utilizzata l'immagine. In caso contrario, il browser passa all'elemento <source>
specificato successivo. Nello snippet HTML precedente, il formato AVIF ha la priorità sul formato WebP, ricorrendo al formato JPEG se non sono supportati né AVIF né WebP.
Un elemento <picture>
richiede un elemento <img>
nidificato al suo interno. Gli attributi
alt
, width
e height
sono definiti nel <img>
e utilizzati
indipendentemente da quale <source>
è selezionato.
L'elemento <source>
supporta anche gli attributi media
, srcset
e sizes
. Come per l'esempio <img>
precedente, indicano al browser quale immagine selezionare in aree visibili diverse.
<picture>
<source
media="(min-resolution: 1.5x)"
srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
>
</picture>
L'attributo media
accetta una condizione dei contenuti multimediali. Nell'esempio precedente, il DPR del dispositivo viene utilizzato come condizione del supporto. Qualsiasi dispositivo con un DPR maggiore o uguale a 1,5 userebbe il primo elemento <source>
. L'elemento <source>
indica al browser che, sui dispositivi con un'area visibile più larga di 768 pixel, l'immagine candidata selezionata viene visualizzata con una larghezza di 500 pixel. Sui dispositivi più piccoli, questa occupa l'intera larghezza dell'area visibile. Combinando gli attributi media
e srcset
, puoi controllare meglio l'immagine da utilizzare.
come illustrato nella tabella seguente, dove vengono valutate diverse larghezze dell'area visibile e proporzioni pixel dei dispositivi:
Larghezza area visibile (pixel) | 1 DPR | 1,5 DPR | 2 DPR | 3 DPR |
---|---|---|---|---|
320 | 500.jpg | 500.jpg | 500.jpg | 1000.jpg |
480 | 500.jpg | 500.jpg | 1000.jpg | 1500.jpg |
560 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
1024 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
1920 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
I dispositivi con un DPR pari a 1 scaricano l'immagine image-500.jpg
, inclusa la maggior parte degli utenti di computer, che visualizzano l'immagine a dimensioni estrinseche di 500 pixel di larghezza. D'altra parte, gli utenti di dispositivi mobili con una DPR pari a 3 scaricano un'immagine image-1500.jpg
potenzialmente più grande, la stessa immagine utilizzata sui computer con un DPR pari a 3.
<picture>
<source
media="(min-width: 560px) and (min-resolution: 1.5x)"
srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
<source
media="(max-width: 560px) and (min-resolution: 1.5x)"
srcset="/image-1000-sm.jpg 1000w, /image-1500-sm.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
>
</picture>
In questo esempio, l'elemento <picture>
viene regolato in modo da includere un elemento <source>
aggiuntivo al fine di utilizzare immagini diverse per dispositivi ampi con un DPR elevato:
Larghezza area visibile (pixel) | 1 DPR | 1,5 DPR | 2 DPR | 3 DPR |
---|---|---|---|---|
320 | 500.jpg | 500.jpg | 500.jpg | 1000-sm.jpg |
480 | 500.jpg | 500.jpg | 1000-sm.jpg | 1500-sm.jpg |
560 | 500.jpg | 1000-sm.jpg | 1000-sm.jpg | 1500-sm.jpg |
1024 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
1920 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
Con questa query aggiuntiva puoi vedere che image-1000-sm.jpg
e
image-1500-sm.jpg
vengono visualizzati in aree visibili di piccole dimensioni. Queste informazioni aggiuntive ti consentono di comprimere ulteriormente le immagini, poiché gli artefatti di compressione non sono altamente visibili con quelle dimensioni e densità, senza compromettere la qualità delle immagini sui dispositivi desktop.
In alternativa, modificando gli attributi srcset
e media
, puoi evitare
di pubblicare immagini di grandi dimensioni in aree visibili di piccole dimensioni:
<picture>
<source
media="(min-width: 560px)"
srcset="/image-500.jpg, /image-1000.jpg 2x, /image-1500.jpg 3x"
>
<source
media="(max-width: 560px)"
srcset="/image-500.jpg 1x, /image-1000.jpg 2x"
>
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
>
</picture>
Nello snippet HTML precedente sono stati rimossi i descrittori della larghezza a favore di quelli delle proporzioni pixel del dispositivo. Le immagini pubblicate su un dispositivo mobile sono limitate a /image-500.jpg
o /image-1000.jpg
, anche sui dispositivi con un DPR pari a 3.
Come gestire la complessità
Quando lavori con le immagini adattabili, potresti avere diverse variazioni di dimensioni e formati per ogni immagine. Nell'esempio precedente, vengono utilizzate varianti per ogni dimensione, ma sono esclusi AVIF e WebP. Quante varianti dovresti avere? Come molti problemi di ingegneria, la risposta tende a essere "dipende".
Sebbene si possa avere la tentazione di avere quante più varianti possibili, ogni variante di immagine aggiuntiva ha un costo e fa un uso meno efficiente della cache del browser. Con una sola variante, ogni utente riceve la stessa immagine, che può quindi essere memorizzata nella cache in modo molto efficiente.
D'altra parte, se ci sono molte varianti, ogni variante richiede un'altra voce della cache. I costi del server possono aumentare e potrebbero peggiorare le prestazioni se la voce della cache della variante è scaduta e l'immagine deve essere recuperata di nuovo dal server di origine.
Inoltre, le dimensioni del documento HTML crescono con ogni variante. Potresti trovarti a inviare più kilobyte di codice HTML per ogni immagine.
Pubblica immagini in base all'intestazione della richiesta Accept
L'intestazione della richiesta HTTP Accept
indica al server i tipi di contenuti che il browser dell'utente riconosce. Queste informazioni possono essere utilizzate dal server per pubblicare il formato dell'immagine ottimale senza aggiungere byte extra alle risposte HTML.
if (request.headers.accept) {
if (request.headers.accept.includes('image/avif')) {
return reply.from('image.avif');
} else if (request.headers.accept.includes('image/webp')) {
return reply.from('image.webp');
}
}
return reply.from('image.jpg');
Lo snippet HTML precedente è una versione semplificata del codice che puoi aggiungere al backend JavaScript del server per scegliere e pubblicare il formato dell'immagine ottimale.
Se l'intestazione della richiesta Accept
include image/avif
, viene pubblicata l'immagine AVIF. In caso contrario, se l'intestazione Accept
include image/webp
, viene pubblicata l'immagine WebP. Se nessuna di queste condizioni è vera, viene pubblicata l'immagine JPEG.
Puoi modificare le risposte in base ai contenuti dell'intestazione della richiesta Accept
in quasi tutti i tipi di server web, ad esempio puoi riscrivere le richieste di immagine sui server Apache in base all'intestazione Accept
utilizzando mod_rewrite
.
Questo è un comportamento simile a quello che potresti trovare su una rete CDN (Image Content Delivery Network). Le CDN di immagini sono soluzioni eccellenti per ottimizzare le immagini e inviare il formato ottimale in base al dispositivo e al browser dell'utente.
La chiave è trovare un equilibrio, generare un numero ragionevole di candidati per le immagini e misurare l'impatto sull'esperienza utente. Immagini diverse possono fornire risultati diversi e le ottimizzazioni applicate a ciascuna immagine dipendono dalle dimensioni all'interno della pagina e dai dispositivi utilizzati dagli utenti. Ad esempio, un'immagine hero a larghezza intera potrebbe richiedere più varianti rispetto alle miniature sulla pagina della scheda di prodotto per l'e-commerce.
Caricamento lento
È possibile indicare al browser di eseguire il caricamento lento delle immagini quando vengono visualizzate
nell'area visibile utilizzando l'attributo loading
. Il valore dell'attributo lazy
indica al browser di non scaricare l'immagine finché non si trova all'interno o nelle vicinanze dell'area visibile. Ciò consente di risparmiare larghezza di banda, consentendo al browser di dare la priorità alle risorse necessarie per il rendering dei contenuti critici già presenti nell'area visibile.
decoding
L'attributo decoding
indica al browser come deve decodificare l'immagine. Il valore async
indica al browser che l'immagine può essere decodificata in modo asincrono, aumentando eventualmente il tempo per il rendering di altri contenuti. Il valore sync
indica al browser che l'immagine deve essere presentata contemporaneamente agli altri contenuti.
Il valore predefinito auto
consente al browser di decidere quale sia la soluzione migliore per l'utente.
Demo di immagini
verifica le tue conoscenze
Quali formati delle immagini supportano la compressione senza perdita di dati?
Quali formati delle immagini supportano la compressione con perdita di dati?
Che cosa dice al browser il descrittore di larghezza (ad esempio 1000w
) in merito a un'immagine candidata specificata in un attributo srcset
?
Cosa indica al browser l'attributo sizes
su un
elemento <img>
a cui è applicato?
srcset
di un elemento <img>
deve essere caricata, in base alle dimensioni dell'area visibile corrente dell'utente.
srcset
dell'elemento <img>
.
A seguire: rendimento dei video
Anche se le immagini sono il tipo di contenuto multimediale più diffuso utilizzato sul web, non sono l'unico da tenere a mente per quanto riguarda le prestazioni. I video sono un altro tipo comune di contenuti multimediali utilizzati sul web e presentano aspetti relativi al rendimento propri. Nel modulo successivo di questo corso, scoprirai alcune tecniche per ottimizzare i video e caricarli in modo efficiente.