Le immagini sono spesso la risorsa più pesante e più diffusa sul web. Di conseguenza, l'ottimizzazione delle immagini può migliorare notevolmente il rendimento sul tuo sito web. Nella maggior parte dei casi, l'ottimizzazione delle 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 per il suo dispositivo.
Le immagini possono essere aggiunte a una pagina utilizzando gli elementi <img>
o <picture>
o la proprietà CSS background-image
.
Dimensioni dell'immagine
La prima ottimizzazione che puoi eseguire per l'utilizzo delle risorse immagine è visualizzare l'immagine nelle dimensioni corrette. In questo caso, il termine dimensioni si riferisce alle dimensioni di un'immagine. Se non vengono prese in considerazione altre variabili, le dimensioni ottimali di un'immagine visualizzata in un contenitore di 500 x 500 pixel sono 500 x 500 pixel. Ad esempio, l'utilizzo di un'immagine quadrata di 1000 pixel significa che l'immagine è due volte più grande del necessario.
Tuttavia, esistono molte variabili che influiscono sulla scelta delle dimensioni delle immagini, rendendo la scelta delle dimensioni delle immagini in ogni caso piuttosto complicata. Nel 2010, quando è stato rilasciato 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 praticamente invariate rispetto all'iPhone 3.
Se avessimo visualizzato tutto a una risoluzione più elevata, il testo e le immagini sarebbero stati ridotti notevolmente, esattamente della metà delle dimensioni precedenti. Invece, 1 pixel è diventato 2 pixel del dispositivo. Questo valore è chiamato rapporto pixel del dispositivo (DPR). L'iPhone 4 e molti modelli di iPhone rilasciati in seguito avevano un DPR di 2.
Se torniamo all'esempio precedente, se il dispositivo ha un DPR di 2 e l'immagine viene visualizzata in un contenitore di 500 x 500 pixel, un'immagine quadrata di 1000 pixel (chiamata dimensione intrinseca) è ora la dimensione ottimale. Analogamente, se il dispositivo ha un DPR di 3, le dimensioni ottimali sono quelle di un'immagine quadrata di 1500 pixel.
srcset
L'elemento <img>
supporta l'attributo srcset
, che consente di specificare un elenco di possibili origini immagine che il browser potrebbe utilizzare. Ogni origine immagine specificata deve includere l'URL dell'immagine e un descrittore della larghezza o della 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à di pixel per suggerire al browser di utilizzare image-500.png
sui dispositivi con un DPR pari a 1, image-1000.jpg
sui dispositivi con un DPR pari a 2 e image-1500.jpg
sui dispositivi con un DPR pari a 3.
Sebbene tutto ciò possa sembrare semplice, il DPR di uno schermo non è l'unico elemento da prendere in considerazione per scegliere l'immagine ottimale per una determinata pagina. Il layout della pagina è un'altra considerazione.
sizes
La soluzione precedente funziona solo se l'immagine viene visualizzata con le stesse dimensioni in pixel CSS su tutti i viewport. In molti casi, il layout di una pagina e le dimensioni del contenitore cambiano a seconda del dispositivo dell'utente.
L'attributo sizes
consente di specificare un insieme di dimensioni di origine, in cui ogni dimensione di origine è costituita da una condizione media e un valore. L'attributo sizes
descrive le dimensioni di visualizzazione previste dell'immagine in pixel CSS. Se combinato con i descrittori della 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 immagini candidate tra cui il browser può scegliere, separate 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, un descrittore di 1000w
indica che la larghezza intrinseca dell'immagine è di 1000 pixel.
Utilizzando queste informazioni, il browser valuta la condizione media nell'attributo sizes
e, in questo caso, riceve l'istruzione che, se la larghezza della visualizzazione del dispositivo supera i 768 pixel, l'immagine viene visualizzata con una larghezza di 500 pixel. Sui dispositivi più piccoli, l'immagine viene visualizzata a 100vw
o a tutta la larghezza della visualizzazione.
Il browser può quindi combinare queste informazioni con l'elenco delle srcset
fonti
di immagini per trovare l'immagine ottimale. Ad esempio, se l'utente utilizza un dispositivo mobile con una larghezza dello schermo di 320 pixel e un DPR di 3, l'immagine viene visualizzata a 320 CSS pixels x 3 DPR = 960 device pixels
. In questo esempio, l'immagine di dimensioni più vicine sarebbe 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 offrire una compressione migliore rispetto a quella dei formati PNG o JPEG, riducendo le dimensioni del file dell'immagine e quindi il tempo di download. Pubblicando immagini in formati moderni, puoi ridurre il tempo di caricamento di una risorsa, il che può comportare un Largest Contentful Paint (LCP) inferiore.
WebP è un formato ampiamente supportato che funziona su tutti i browser moderni. WebP spesso offre una compressione migliore rispetto a JPEG, PNG o GIF, in quanto offre sia la compressione con perdita sia la compressione senza perdita di dati. WebP supporta anche la trasparenza del canale alfa anche quando viene utilizzata la compressione con perdita di dati, una funzionalità non offerta dal codec JPEG.
AVIF è un formato immagine più recente e, anche se non è ampiamente supportato come WebP, gode di un supporto ragionevolmente decente su tutti i browser. AVIF supporta sia la compressione con perdita di dati sia quella senza perdita di dati e i test hanno mostrato risparmi superiori al 50% rispetto al JPEG in alcuni casi. AVIF offre anche 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 tramite la quantizzazione e le informazioni aggiuntive sul colore possono essere eliminate utilizzando il sottocampionamento di crominanza. La compressione con perdita è più efficace sulle 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 sono molto meno evidenti in immagini così dettagliate. Tuttavia, la compressione con perdita di dati potrebbe essere meno efficace con le immagini contenenti bordi netti, come disegni a linee, dettagli simili o testo. La compressione con perdita di dati può essere applicata alle 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 adiacenti. La compressione senza perdita di dati viene utilizzata per i formati di immagine 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 diversi livelli di compressione fino a trovare un buon compromesso tra la qualità dell'immagine e le dimensioni del file. Alcuni servizi di ottimizzazione delle immagini avanzati possono farlo automaticamente, ma potrebbero non essere economicamente convenienti per tutti gli utenti.
Elemento <picture>
L'elemento <picture>
offre una maggiore flessibilità per la specifica di più
immagini candidate:
<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 elementi <source>
all'interno dell'elemento <picture>
, puoi aggiungere il supporto per le immagini AVIF e WebP, ma utilizzare i formati di immagini legacy più compatibili se il browser non supporta i formati moderni. Con questo approccio, il browser sceglie il primo elemento <source>
specificato che corrisponde. Se riesce a visualizzarla in quel formato, la utilizza. In caso contrario, il browser passa all'elemento <source>
specificato successivo. Nell'snippet HTML precedente, il formato AVIF ha la precedenza sul formato WebP, che viene utilizzato come fallback se né AVIF né WebP sono supportati.
Un elemento <picture>
richiede un elemento <img>
nidificato al suo interno. Gli attributi alt
, width
e height
sono definiti in <img>
e utilizzati indipendentemente dal <source>
selezionato.
L'elemento <source>
supporta anche gli attributi media
, srcset
e sizes
. Analogamente all'esempio <img>
precedente, indicano al browser quale immagine selezionare in viewport diversi.
<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 multimediale. Nell'esempio precedente, il DPR del dispositivo viene utilizzato come condizione multimediale. Qualsiasi dispositivo con un DPR maggiore o uguale a 1,5 utilizzerà il primo elemento <source>
. L'elemento <source>
indica al browser che, sui dispositivi con un viewport più ampio di 768 pixel, l'immagine candidata selezionata viene visualizzata con una larghezza di 500 pixel. Sui dispositivi più piccoli, occupa l'intera larghezza dell'area visibile. Combinando gli attributi media
e srcset
, puoi avere un controllo più preciso sull'immagine da utilizzare.
Questo è illustrato nella tabella seguente, in cui vengono valutate diverse larghezze del viewport e proporzioni in pixel del dispositivo:
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 con una dimensione esterna di 500 pixel di larghezza. Invece, gli utenti di dispositivi mobili con un DPR di 3 scaricano un'immagine potenzialmente più grande, ovvero la stessa utilizzata sui computer con un DPR di 3.image-1500.jpg
<picture>
<source
media="(min-width: 561px) 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 modificato in modo da includere un elemento <source>
aggiuntivo per utilizzare immagini diverse per i dispositivi ampi con un elevato rapporto DPR:
Larghezza area visibile (pixel) | 1 DPR | 1,5 DPR | 2 DPR | 3 DPR |
---|---|---|---|---|
320 | 500.jpg | 500.jpg | 1000-sm.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 viewport di piccole dimensioni. Queste informazioni aggiuntive
ti consentono di comprimere ulteriormente le immagini, poiché gli artefatti di compressione non sono molto visibili con queste dimensioni e densità, senza compromettere la qualità dell'immagine
sui computer.
In alternativa, modificando gli attributi srcset
e media
, puoi evitare di pubblicare immagini di grandi dimensioni in viewport di piccole dimensioni:
<picture>
<source
media="(min-width: 561px)"
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, i descrittori della larghezza sono stati rimossi a favore
dei descrittori del rapporto 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 di 3.
Come gestire la complessità
Quando lavori con le immagini adattabili, potresti trovarti a dover gestire molte varianti di dimensioni e formati diversi per ogni immagine. Nell'esempio precedente vengono utilizzate le varianti per ogni dimensione, ma vengono esclusi AVIF e WebP. Quante varianti dovresti avere? Come per molti problemi di ingegneria, la risposta tende a essere "dipende".
Sebbene possa essere allettante avere il maggior numero possibile di varianti per ottenere la migliore corrispondenza, ogni variante di immagine aggiuntiva ha un costo e rende meno efficiente l'utilizzo della cache del browser. Con una sola variante, ogni utente riceve la stessa immagine, quindi può essere memorizzata nella cache in modo molto efficiente.
D'altra parte, se sono presenti molte varianti, ogni variante richiede un'altra voce della cache. I costi del server possono aumentare e le prestazioni potrebbero peggiorare se la voce della cache della variante è scaduta e l'immagine deve essere recuperata di nuovo dal server di origine.
A parte questo, le dimensioni del documento HTML aumentano con ogni variante. Potresti dover inviare più kilobyte di codice HTML per ogni immagine.
Pubblicare le immagini in base all'intestazione della richiesta Accept
L'intestazione della richiesta HTTP Accept
indica al server i tipi di contenuti supportati dal browser dell'utente. Queste informazioni possono essere utilizzate dal server per pubblicare il formato immagine ottimale senza aggiungere byte aggiuntivi 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 tuo server per scegliere e pubblicare il formato di immagine ottimale.
Se l'intestazione della richiesta Accept
include image/avif
, l'immagine AVIF viene pubblicata. In caso contrario, se l'intestazione Accept
include image/webp
, l'immagine WebP viene pubblicata. Se nessuna di queste condizioni è vera, viene visualizzata 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 immagini sui server Apache in base all'intestazione Accept
utilizzando mod_rewrite
.
Questo comportamento non è molto diverso da quello che potresti trovare su una rete CDN (Content Delivery Network) per immagini. 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.
L'importante è trovare un equilibrio, generare un numero ragionevole di immagini candidate e misurare l'impatto sull'esperienza utente. Immagini diverse possono dare risultati diversi e le ottimizzazioni applicate a ogni immagine dipendono dalle sue dimensioni all'interno della pagina e dai dispositivi utilizzati dagli utenti. Ad esempio, un'immagine hero intera potrebbe richiedere più varianti rispetto alle miniature nella pagina della scheda di prodotto di un sito di e-commerce.
Caricamento lento
È possibile indicare al browser di caricare le immagini in modo lazy quando appaiono nel viewport utilizzando l'attributo loading
. Un valore dell'attributo pari a lazy
indica al browser di non scaricare l'immagine finché non si trova all'interno (o nelle vicinanze) dell'area visibile. In questo modo, si risparmia larghezza di banda, consentendo al browser di dare la priorità alle risorse necessarie per visualizzare i contenuti critici già presenti nell'area visibile.
decoding
L'attributo decoding
indica al browser come decodificare l'immagine. Un valore di async
indica al browser che l'immagine può essere decodificata in modo asincrono, migliorando eventualmente il tempo di rendering di altri contenuti. Un valore sync
indica al browser che l'immagine deve essere presentata contemporaneamente agli altri contenuti.
Il valore predefinito auto
consente al browser di decidere cosa è meglio per l'utente.
Demo di immagini
Verifica le tue conoscenze
Quali formati di immagine supportano la compressione senza perdita di dati?
Quali formati di immagine supportano la compressione con perdita?
Che cosa dice il descrittore della larghezza (ad esempio 1000w
) al browser in merito a un'immagine candidata specificata in un attributo srcset
?
Che cosa dice l'attributo sizes
al browser in merito a un elemento <img>
a cui è applicato?
srcset
dell'elemento <img>
deve essere caricato,
date le dimensioni dell'area visibile corrente dell'utente.
srcset
dell'elemento <img>
.
A seguire: rendimento dei video
Sebbene le immagini siano il tipo di file multimediale più diffuso utilizzato sul web, non sono affatto l'unico elemento da tenere presente in termini di rendimento. I video sono un altro tipo comune di contenuti multimediali utilizzati sul web e presentano considerazioni sul rendimento specifiche. Nel modulo successivo di questo corso, scoprirai alcune tecniche per ottimizzare i video e caricarli in modo efficiente.