Immagini responsive in CSS con background-image

Nella quasi totalità dei casi, quando parliamo di immagini responsive, ci riferiamo alle immagini inline in HTML. Questo perché prima del tag <picture> o dell’attributo srcset , era l’unica soluzione possibile. Con i CSS, potremmo usare le media-query, quindi non ci dovremmo preoccupare.. anzi no.

Adesso è tempo di mettere di nuovo mano a questa tecnica, usandone una più avanzata: il background image-set.

image-set() e risoluzione

Proprio come facciamo per le immagini inline, lasciamo che il browser scelga l’immagine di grandezza più adatta in base alla densità dello schermo dell’utente (o alla rete, o ad altri fattori). Vediamo rapidamente come usare la sintassi image-set:

Avrete sicuramente notato le similitudini tra questa sintassi e quella di srcset , che si basa difatti proprio su questa!

Due righe di storia

image-set() è stata il primo storico miglio per le responsive images ed è stato proprio lui a servire come base per l’attributo <img srcset=""> , che oggi è sicuramente più diffuso. Poi sono arrivate le CSS media queries e image-set è stato completamente ignorato, perfino dallo stesso Responsive Images Community Group.

Nonostante il supporto sia in fase di sviluppo, non tutti i browser supportano pienamente image-set() . Mentre scriviamo questo articolo IE, Edge e Firefox non lo supportano affatto, mentre per tutti gli altri è necessario usare il prefisso -webkit  in questo modo

Per tutti gli altri casi, e per una maggiore compatibilità, è consigliato usare le CSS media queries.

Media queries e risoluzione

Se vogliamo quindi supportare le immagini con una risoluzione più alta per gli schermi che lo consentono, il modo che offre maggiore compatibilità è quello delle media queries con un parametro di densità:

La prima cosa da notare è che abbiamo di nuovo dovuto usare un attributo con il prefisso -webkit , necessario per la retrocompatibilità. Abbiamo poi indicato l’attributo min-resolution  con una risoluzione di 192dpi, soltanto gli schermi con questa densità maggiore o uguale a questa saranno coinvolti.

Come possiamo notare, questo sistema è più potente del precedente perché ci permette di gestire più facilmente le risoluzioni. Nell’esempio precedente di background:image-set() , infatti, abbiamo dovuto indicare la densità con “1x” o “2x”, che non ci dicono davvero nulla.

 

 

Preparare le immagini per Lazyload JS in WordPress

In un precedente articolo, abbiamo visto come integrare il caricamento on scroll delle immagini con Lazyload JS. Possiamo naturalmente applicare lo stesso meccanismo ad un tema WordPress.

Nella pagina di un post, quindi ad esempio nel file single.php , WordPress posizionerà le immagini contenute nell’articolo come responsive images e lo farà usando la tecnica dell’attributo srcset del tag <img> . Se non conoscete questo meccanismo, è molto semplice: all’interno del tag <img> sono presenti diverse dimensioni della stessa immagine e la loro larghezza (width). Il browser selezionerà automaticamente quella adatta alla densità (leggi DPI) dello schermo dell’utente.

Vediamo un esempio di <img> responsive generata da WordPress:

In questo esempio è ben chiaro che l’immagine è presente in varie misure, dalla più piccola, larga appena 300px (300w) alla più grande da 1280px di larghezza (1280w). Quello che chiediamo al browser è di prendere dal server e mostrarci la più adatta alla densità del nostro schermo.

Adesso facciamo andare d’accordo Lazyload con le responsive image.

Come abbiamo visto nell’articolo relativo a LazyLoad JS, esso si basa sull’attributo data-srcset  e non sul srcset  di default per le immagini. Vediamo allora come far generare correttamente i tag delle immagini dei nostri post per farli processare allo script. Ricordate che questo processo è retroattivo: la modifica funzionerà automaticamente per tutti i nostri post!

Iniziamo aggiungendo questo codice al file functions.php  del nostro tema.

La function replace_img_src()  si occuperà di modificare automaticamente tutti i tag <img> presenti nel contenuto del post e riscriverà, per ciascuno, gli attributi data-srcset , scrset  e src. A questo punto, dobbiamo includere lo script Lazyload e inizializzarlo.

Il modo più semplice per farlo è incollare questo codice all’interno del file footer.php  del nostro tema, subito prima della chiusura del tag <body> :

Fatto, happy (lazy) loading!

Lazyload JS: caricamento immagini progressivo on scroll

Lazyload JS (chiamato anche vanilla-lazyload) è uno script che permette il caricamento delle immagini allo scroll della pagina (effetto detto appunto “lazy load”). Perché lo facciamo? Innanzitutto per velocizzare il caricamento della pagine e poi per fornire una migliore User Experience: soltanto le immagini che effettivamente sono visibili nel viewport saranno richieste al server e mostrate all’utente.

Sembra banale ma.. perché richiedere risorse al server che non verranno mai usate? Questo porta anche ad un secondo vantaggio: risparmiare risorse e banda consumata. Se usiamo un servizio CDN risparmieremo decisamente molte richieste.

Lazyload è uno script di soli 3Kb che non ha dipendenze, cioè può essere usato senza includere jQuery o altre librerie. È scritto in javascript “liscio” (detto vanilla) e ha un moltissime di opzioni di configurazione che vedremo in questo articolo.

Includiamo lo script

Innanzitutto includiamo lo script nelle nostre pagine. Il consiglio è quello di farlo attraverso un CDN, in modo da non caricare nessun file sul nostro server e sfruttare l’ottimizzazione di Cloudflare:

 

A questo punto ci sono vari modi per sfruttare le sue potenzialità. Tutto dipende da come sono posizionate le immagini nel nostro codice e che obiettivo vogliamo raggiungere. Vediamo tre esempi pratici:

Caso 1: immagini in-line

Usiamo questo semplice esempio per il caso più diffuso, cioè un immagine da caricare una volta che è “nello schermo”:

HTML

Javascript

Caso 2: immagini responsive con srcset

In questo caso usiamo la tecnica delle misure srcset , sostituendolo con l’attributo data-original-set :

HTML

Javascript

Caso 3: con il tag <picture>

Se usiamo il tag <picture> per le immagini responsive, possiamo usare un codice analogo a questo:

HTML

Javascript

Caso 4: immagini di sfondo CSS

Se volessimo applicare l’effetto lazyload a immagini posizionate come background-image  in CSS, possiamo farlo in questo modo:

HTML

Javascript

Ulteriori vantaggi

È SEO-friendly perché non nasconde le immagini ai motori di ricerca.

Funziona anche in presenza di altri script, come jQuery, Angular, React o Vue.

È molto più veloce del famoso jQuery lazyload: si stima infatti che sia circa 6 volte più veloce.

Aggiungere la compressione gzip ai file SVG su nginx

I file SVG sono un modo eccezionale per avere delle immagini vettoriali senza alcuna perdita di qualità. A differenza di altre immagini compresse, come jpg o png, i file SVG sono di fatto dei file di testo (simili all’XML) che vengono interpretati come immagini contenenti forme geometriche, testi, linee. Proprio per questa loro natura, possono essere serviti dal nostro webserver usando l’algoritmo gzip con un guadagno notevole il termini di trasferimento dati (nell’ordine del 70-80%) e quindi di User Experience.

In questa guida vedremo come misurare i benefici della compressione gzip applicata ai file SVG, come abilitarla sul popolare webserver nginx e come verificare che tutto funzioni.

Un piccolo test

Per prima cosa, testiamo localmente quanto possiamo guadagnare in termini di spazio su un file SVG. Proviamo a scaricare un file di dominio pubblico ed a gzipparlo, comparando successivamente i filesize:

Abbiamo scaricato il file Artctig_big.svg usando il comando wget.  Come possiamo vedere il file ha un peso di 1468466 byte, cioè 1,46Mb. Proviamo a comprimerlo con gzip:

Verifichiamone il peso:

Il file SVG è passato da 1,46Mb a 423Kb: il nuovo file è grande il 29% dell’originale!

Configuriamo nginx

Applichiamo tutto questo ad nginx per assicurarci che tutti i file SVG vengano serviti compressi con gzip.

Per prima cosa assicuriamoci che SVG sia tra i mime types, andando a guardare nel file relativo:

Troviamo questa riga e, nel caso non ci fosse, aggiungiamola:

A questo punto apriamo il file di configurazione:

Cerchiamo la voce gzip types e aggiungiamo image/svg+xml alla fine, come in questo esempio:

Salviamo e riavviamo nginx:

Testiamo il funzionamento

Per testarne il funzionamento, possiamo usare un tool come questo. La pagina ci darà un esito come questo:

Usare la compressione gzip in Apache e nginx per aumentare la velocità

La velocità di caricamento sembra essere sempre più il centro focale del web. Come vi abbiamo già raccontato, costruire un sito veloce ha molteplici aspetti positivi e incide radicalmente sulla UX, sul SEO, e sulla fedeltà degli utenti, specialmente se sono Mobile.

Uno dei più importanti processi alla base dell’ottimizzazione della velocità di caricamento è sicuramente la compressione HTTP, ovvero la capacità del server di inviare all’utente le pagine (e in generale i contenuti statici come le immagini e gli script) come contenuto compresso, in modo che il browser stesso li decomprima e li visualizzi. Per farlo ci deve essere un’intesa tra il browser dell’utente, che dice al server quali formati è in grado di leggere, e il server che gli risponde in uno dei formati possibili. Teniamo presente che tutti i browser moderni sono capaci di accettare vari tipi di compressione e tutti sono capaci di adattarsi alle varie richieste.

In questo tutorial ci focalizzeremo sulla compressione gzip, una delle più diffuse ed efficaci e vedremo come abilitarla a livello server e controllare che la compressione sia attiva. In più eseguiremo un test finale per capire quanto è efficace la compressione http. Studieremo come abilitarla sui più diffusi webserver, ovvero Apache ed nginx

Apache usa due moduli principali per la compressione e decompressione:

  1. mod_deflate
  2. mod_gzip

Entrambi usano lo stesso algoritmo di base ed ottengono risultati praticamente identici. Tuttavia, nelle recenti versioni di Apache 2.x.x troviamo già installato mod_deflate e questo è già un vantaggio in termini di velocità di sviluppo. In ogni caso, per verificare che il modulo sia installato, lanciamo uno di questi comandi

oppure

Se nella lista è presente il deflate_module oppure il gzip_module siamo pronti per proseguire.

Abilitiamo gzip in Apache in .htaccess con mod_deflate

Per prima cosa, creiamo un file .htaccess, oppure apriamo il file già esistente. Aggiungiamo queste righe:

Abilitiamo gzip in Apache in .htaccess con mod_gzip

Le versioni più vecchie di Apache hanno installato di default il mod_gzip, con le stesse identiche funzionalità di mod_deflate. Se decidiamo di usare mod_gzip quindi, il procedimento è del tutto simile: creiamo un file .htaccess oppure apriamo il file già esistente. Aggiungiamo queste righe:

Abilitiamo gzip su nginx

Per abilitare gzip su nginx, è necessario intervenire sul suo file di configurazione generale. Se da un late impone una difficoltà maggiore, dall’altra è un setting universale che verrà applicato automaticamente su tutti i siti presenti sullo stesso server. Il file nginx.conf  è solitamente posizionato in /usr/local/nginx/conf/nginx.conf , /etc/nginx/nginx.conf  oppure /usr/local/etc/nginx/nginx.conf . Andiamo a modificarlo, ad esempio con l’editor vim

ed aggiungiamo queste direttive

Salviamo il file e riavviamo nginix con il comando

Come verificare se gzip è abilitato

A questo punto, non ci resta che verificare se i file statici vengono inviati al nostro browser in modalità compressa gzip. Se usate Chrome, accedete alla finestra Ispeziona (tasto destro sulla pagina). In Network, selezioniamo un file CSS o JS servito direttamente dal nostro server, se troviamo la stringa Content-Encoding: gzip  tra le Response Headers abbiamo correttamente abilitato la compressione.

 

Online sono presenti vari tool per verificare se gzip è abilitato, provate ad esempio checkgzipcompression.com