velocizzare-sito-web come-velocizzare-un-sito-web

PageSpeed Insights: come velocizzare un sito web

caricamento-pagina-web
  1. PageSpeed Insights di Google per velocizzare il caricamento delle pagine web
  2. Visualizzazione dei primi contenuti
  3. Visualizzazione dei primi contenuti utili
  4. Indice velocità
  5. Prima inattività CPU
  6. Tempo per interattività
  7. Potenziale ritardo prima interazione
  8. Tempo di blocco totale
  9. Visualizzazione dei contenuti più grandi
  10. Variazione layout cumulativa
  11. Usa immagini di dimensioni adeguate
  12. Codifica in modo efficace le immagini
  13. Pubblica immagini in formati più recenti
  14. Rimanda immagini fuori schermo
  15. Assicurati che il testo rimanga visibile durante il caricamento dei caratteri web
  16. Pubblica le risorse statiche con criteri della cache efficaci
  17. Elimina le risorse di blocco della visualizzazione
  18. Minimizza CSS e JavaScript
  19. Evita payload di rete enormi
  20. Evita un DOM di dimensioni eccessive
  21. Riduci il tempo di esecuzione di JavaScript
  22. Limita il codice di terze parti
  23. Attiva la compressione del testo
  24. Precollegati alle origini necessarie
  25. Evita i reindirizzamenti tra più pagine
  26. Precarica le richieste fondamentali
  27. Usa formati video per i contenuti animati
  28. Riduci i tempi di risposta del server
  29. Evita document.write()
1.

PageSpeed Insights di Google per velocizzare il caricamento delle pagine web

PageSpeed Insights di Google è un utility che si focalizza sui dati inerenti la velocità di caricamento di una pagina web (fattore che ne influenza positivamente il ranking), riportandone le reali prestazioni su dispositivi mobile e desktop e aiutando a comprenderle attraverso opportuni suggerimenti di ottimizzazione per migliorarle.

PSI utilizza il tool Google Lighthouse per analizzare l'URL servitogli, generando un punteggio, basato su diverse metriche, che ne sintetizza il rendimento.
Ogni metrica è contrassegnata da un'icona colorata:

velocizzare-caricamento-pagine-web

Una volta che Lighthouse ha completato la raccolta delle metriche prestazionali generate dal tuo sito web le converte in un punteggio compreso tra 0 e 100.

caricamento-pagine-web-lento

Il punteggio viene determinato solo dalle metriche delle prestazioni; le sezioni "Opportunità" e "Diagnostica" non contribuiscono direttamente al punteggio complessivo ottenuto.
Grazie a questi dati gli sviluppatori possono comprendere dove l'esperienza utente sul loro sito risulta più frustrante e come possa essere migliorata.

A differenza di PSI, Google Lightouse è un audit tool integrato in Google Chrome che fornisce un elenco completo di opportunità di miglioramento mancanti a una pagina web, ovvero dei consigli personalizzati non solo sulle performance (ovvero, il target di PSI), ma anche su accessibilità, SEO, con il fine di incrementarne il rendimento e la qualità.
Eseguiti tutta una serie di controlli sull'URL servitogli, genera un rapporto del quale i controlli non riusciti fungeranno da indicatori su dove sarebbe opportuno intervenire.

Aggiornamento ottobre 2022. Ora la Diagnostica dei problemi prestazionali include le altre categorie Lighthouse, ovvero accessibilità, best practice e SEO.

Gran parte della variabilità del punteggio di prestazione generale e dei punteggi metrici non è dovuta a Lighthouse.
Quando il tuo punteggio di performance oscilla di solito è a causa di cambiamenti nelle condizioni sottostanti, quali ad esempio:

Che cos'altro?

La verità è che le prestazioni sono relative.
Un sito potrebbe essere veloce per un utente (su una rete ADSL con un dispositivo potente) ma lento per un altro utente (su una rete lenta con un dispositivo di fascia bassa).
Due siti potrebbero terminare il caricamento nello stesso identico lasso di tempo, ma potrebbe sembrare che uno di essi si carichi più velocemente (se carica il contenuto progressivamente anziché attendere fino alla fine per visualizzarlo).
Potrebbe sembrare che un sito si carichi rapidamente, ma che poi risponda lentamente all'interazione dell'utente.
In altre parole, una pagina potrebbe tecnicamente avere un tempo di caricamento rapido, ma quel tempo non corrispondere a come un utente lo sperimenta effettivamente.
Pertanto, quando si parla di prestazioni è importante essere precisi e fare riferimento ad esse in termini di criteri oggettivi che possano essere misurati quantitativamente: questi criteri sono noti come metriche.

Negli ultimi anni, i membri del team di Chrome, in collaborazione con il W3C, hanno lavorato per standardizzare una serie di nuove API e metriche che misurano più accuratamente il modo in cui gli utenti sperimentano le prestazioni di una pagina web.
Tali metriche vengono inquadrate attorno ad alcune domande chiave:

Le metriche delle prestazioni sono generalmente misurate in due modi: in laboratorio, con l'utilizzo di strumenti che simulano il caricamento di una pagina in un ambiente coerente e controllato; sul campo, con una varietà di dispositivi e condizioni di rete che permettono di acquisire un'esperienza utente reale.
Nessuno di questi scenari è necessariamente migliore o peggiore dell'altro, infatti in genere vengono utilizzati entrambi per garantire dati affidabili.

I test delle prestazioni in laboratorio, per quanto essenziali per lo sviluppo di nuove funzionalità, non riflettono necessariamente il modo in cui tutti gli utenti sperimentano le prestazioni del tuo sito in natura, realmente.

L'unico modo per sapere veramente come si comporta il tuo sito con i tuoi utenti è misurare effettivamente le sue prestazioni mentre lo caricano e interagiscono con esso.
Questo tipo di misurazione è comunemente indicato come monitoraggio utente reale (Real User Monitoring, o RUM ).
RUM si affida alle API JavaScript del browser per raccogliere statistiche sulle prestazioni dei siti a seguito di richieste provenienti da utenti reali, rilevando la velocità e acquisendo tempistiche che misurano le varie fasi del caricamento dei documenti e delle risorse.

Esistono molti tipi di metriche rilevanti per il modo in cui gli utenti percepiscono le prestazioni:

Andiamo adesso alle metriche di PageSpeed Insights.
Tali metriche si concentrano principalmente sulle prestazioni e sono utili per ottenere una comprensione generale delle performance dei siti web, oltre che per confrontare le prestazioni di ognuno di essi con quelle dei loro concorrenti.

2.

Visualizzazione dei primi contenuti

La visualizzazione dei primi contenuti (FCP, acronimo di First Contentful Paint ) è una delle metriche prestazionali tracciate nel rapporto Lighthouse che acquisisce alcuni degli aspetti relativi alla velocità di caricamento di una pagina web.

FCP misura quanto tempo impiega il browser per eseguire il rendering dei primi contenuti del DOM dopo che un utente accede alla tua pagina.
Ad esempio, le immagini sono considerate contenuto del DOM, mentre qualsiasi cosa si trovi all'interno di un <iframe> non è inclusa nell'albero del DOM.

Il tuo punteggio FCP è un confronto tra il tempo che impiega la tua pagina a visualizzare i primi contenuti e i dati FCP di tanti altri siti web, estrapolati dall'archivio HTTP.

Una problematica particolarmente importante per la visualizzazione dei primi contenuti è il tempo di caricamento dei caratteri, pertanto è bene assicurarsi che il testo rimanga visibile durante il caricamento di quei contenuti ai quali viene associato un web font.

3.

Visualizzazione dei primi contenuti utili

La visualizzazione dei primi contenuti utili (FMP, acronimo di First Meaningful Paint ) è una metrica pressoché simile alla precedente (FCP) che si basa su dati reali prodotti dalle prestazioni di un sito web, ma che tuttavia può differire quando, ad esempio, ci sono contenuti above the fold all'interno di un <iframe>, che non vengono registrati dalla FCP; in tal caso il punteggio FMP sarà inferiore al punteggio FCP.

4.

Indice velocità

L'indice di velocità (Speed Index ) misura la velocità con cui i contenuti vengono visualizzati durante il caricamento della pagina, calcolando la progressione visiva tra un frame e l'altro.
Lighthouse utilizza quindi il modulo Speedline di Node.js per generare il punteggio dell'indice di velocità, basato su un confronto tra l'indice di velocità della tua pagina e il medesimo indice di tanti altri siti web ricavato dai dati reali dell'archivio HTTP.

Come per le altre metriche, consultando i consigli suggeriti è possibile scoprire come affrontare le opportunità identificate nel rapporto Lighthouse.

5.

Prima inattività CPU

La prima inattività CPU (First CPU Idle) misura quanto tempo impiega una pagina a diventare minimamente interattiva.
Una pagina è considerata tale quando:

6.

Tempo per interattività

Alcuni siti ottimizzano la visibilità dei contenuti a spese dell'interattività, creando un'esperienza utente potenzialmente frustrante; il sito sembra essere pronto, ma quando l'utente tenta di interagire con esso non accade nulla.

Il Tempo per interattività (Time to Interactive) misura quanto tempo impiega una pagina a diventare completamente interattiva, dal momento in cui inizia a caricarsi a quando viene visivamente riprodotta (compreso il caricamento degli script iniziali, se presenti) e risulta in grado di rispondere in modo affidabile e rapido all'input dell'utente.

Sia First CPU Idle che TTI misurano quando la pagina è pronta per l'input dell'utente, ma mentre la prima metrica si verifica quando l'utente può iniziare a interagire con la pagina, la seconda scatta quando l'utente è in grado di interagire completamente con la stessa pagina.

Miglioramenti che possono avere effetti importanti sulla metrica in questione sono le ottimizzazioni relative al codice JavaScript, proprio e di terze parti.

7.

Potenziale ritardo prima interazione

Sappiamo tutti quanto sia importante fare una buona prima impressione quando si creano esperienze sul web.
Una buona prima impressione può fare la differenza tra qualcuno che diventa un utente fedele o che se ne va e non torna più a farci visita.
Cerchiamo di capire cosa genera una buona impressione e come si misura il tipo di impressione che si darà ai propri utenti.

Sul Web le prime impressioni possono assumere forme molte diverse; prime impressioni sul design e sul fascino visivo di un sito, nonché prime impressioni sulla sua velocità e reattività.
A proposito di velocità quella con cui il tuo sito può disegnare pixel sullo schermo è solo una parte del nostro discorso; altrettanto importante è quanto sia reattivo il tuo sito quando gli utenti cercano di interagire con quei pixel.

Il potenziale ritardo prima interazione (First Input Delay) misura il tempo che intercorre tra la prima volta in cui un utente interagisce con il tuo sito e il momento in cui il browser è effettivamente in grado di rispondere a tale interazione.
Tale ritardo di input (o latenza di input) si verifica perché il thread principale del browser è impegnato a fare qualcos'altro, quindi non può ancora rispondere all'utente.
Un motivo comune per cui ciò può accadere è che il browser sta analizzando un file JavaScript di grandi dimensioni, e mentre lo fa non può eseguire alcun listener di eventi perché il JavaScript che sta caricando potrebbe dirgli di fare qualcos'altro.
In altre parole, il client esegue delle richieste di rete per alcune risorse (molto probabilmente file CSS e JS) e, una volta terminato il download di tali risorse, queste vengono elaborate sul thread principale; il tutto si traduce in periodi in cui il thread principale rimane momentaneamente occupato, senza poter soddisfare gli input dell'utente.

In genere, i ritardi dei primi input si verificano tra First Contentful Paint (FCP) e Time to Interactive (TTI) perché la pagina ha reso, si, parte del suo contenuto, ma non è ancora interattivamente affidabile.
Potrebbe intercorrere un importante lasso di tempo tra FCP e TTI.
Se un utente tenta di interagire con la pagina durante quel periodo (ad esempio, cliccando su un bottone), molto probabilmente si verificherà un ritardo tra l'attivazione dell'evento (clic) e il momento in cui il thread principale sarà in grado di rispondere.
Poiché l'input si verifica mentre il browser è nel mezzo dell'esecuzione di un'attività, bisognerà attendere il completamento di quest'ultima prima di poterlo soddisfare; il tempo di attesa è il valore FID per quell'utente su quella pagina.

Partendo dal presupposto che il ritardo di qualsiasi input può determinare una brutta esperienza per l'utente, la misurazione del primo ritardo di input risulta particolatmente importante per alcuni motivi:

Le soluzioni consigliate su come i siti dovrebbero correggere i primi ritardi di input elevati (suddivisione del codice, caricare meno JavaScript in anticipo) non sono necessariamente le stesse soluzioni per correggere ritardi di input dopo il caricamento della pagina.
FID è una metrica che misura la reattività di una pagina durante il caricamento, e come tale si concentra solo su eventi di input come clic, tocchi e pressioni di tasti.
Altre interazioni, come lo scorrimento e lo zoom, hanno risvolti sulle prestazioni completamente diversi, oltre al fatto che i browser sono spesso in grado di nascondere la loro latenza eseguendoli su un thread separato.
In altre parole, FID si concentra sulla reattività, mentre lo scorrimento e lo zoom sono azioni più correlate all'animazione e il loro impatto sulla qualità delle prestazioni dovrebbe essere valutato separatamente.

Ciononostante, non tutti gli utenti interagiranno con il tuo sito ogni volta che lo andranno a visitare, e non tutte le interazioni saranno rilevanti per il FID.
Inoltre, le prime interazioni di alcuni utenti potrebbero venire in essere in cattivi momenti (quando il thread principale rimane occupato per un lungo periodo di tempo), quelle di altri utenti invece in momenti migliori (quando il thread principale è completamente inattivo).
Ciò significa che alcuni utenti non avranno valori FID, altri avranno valori FID bassi e altri ancora valori FID elevati.

E` quasi scontato aggiungere che FID è una metrica che può essere misurata solo sul campo, in quanto richiede un utente reale per interagire con la tua pagina.

A meno che tu non abbia un motivo specifico per concentrarti su una particolare metrica, di solito è meglio dedicarsi al miglioramento del punteggio di rendimento complessivo.
Utilizza la sezione "Opportunità" del rapporto Lighthouse per determinare quali miglioramenti avranno maggior valore per la tua pagina; più significativa è l'opportunità maggiore sarà l'effetto che avrà sul punteggio delle performance.
Ogni suggerimento in questa sezione stima quanto più velocemente verrà caricata la pagina qualora il miglioramento venisse implementato

C'è anche la sezione "Diagnostica", che fornisce ulteriori informazioni sulle migliori pratiche alle quali una pagina potrebbe aderire per raggiungere prestazioni sempre più efficienti.

8.

Tempo di blocco totale

Il tempo di blocco totale (TBT, che sta per Total Blocking Time) è una metrica che misura (in millisecondi) il tempo totale in cui una pagina è bloccata sufficientemente a lungo da impedire la risposta all'input dell'utente (clic del mouse, pressioni della tastiera, tocchi dello schermo).
I clic, i tocchi, spesso non funzionano perché i loro gestori (ovvero, i listener di eventi) non sono ancora stati allegati.
Viene calcolata aggiungendo la parte bloccante di tutte le attività lunghe tra First Contentful Paint e Time to Interactive.
Qualsiasi attività (task ) che viene eseguita per più di 50 ms è un'attività lunga: la quantità di tempo accumulata dopo 50 ms è la parte bloccante.
Ad esempio, se Lighthouse rileva un'attività lunga 70 ms, la porzione di blocco corrisponde a 20 ms.
Ma perché proprio 50ms?
Il modello RAIL suggerisce di elaborare gli eventi di input dell'utente in 50 ms per garantire una risposta visibile entro 100 ms; in caso contrario la connessione tra azione e reazione si interrompe.

Un long task può tenere occupato a lungo il thread principale, che rimane bloccato perché il browser non può interrompere un'attività in corso, rendendo la pagina non reattiva all'input dell'utente, pur sembrando pronta a rispondere.
Pertanto, nel caso in cui un utente interagisca con la pagina nel mezzo di un'attività lunga, il browser deve attendere il completamento dell'attività prima di poter rispondere.
Se l'attività è abbastanza lunga è probabile che l'utente noterà il ritardo e percepirà la pagina come lenta.

Un long task può avere diverse cause, tra cui l'esecuzione di codice JavaScript non realmente necessario per il caricamento della pagina.
Ridurne il payload con la suddivisione del codice o il caricamento efficiente di JavaScript di terze parti dovrebbe migliorare il punteggio TBT.

Un'altra delle cause potrebbe essere la dichiarazione inefficiente di codice JavaScript, ad esempio una chiamata all'oggetto document, mediante il metodo querySelectorAll, che restituisce centinaia di nodi potrebbe risultare troppo dispendiosa per la CPU e aumentare i tempi di esecuzione.
Una soluzione per migliorare il punteggio TBT potrebbe essere quella di rifattorizzare il codice, utilizzando selettori più specifici che restituiscano i nodi a gruppi di decine.
In altre parole, è buona pratica organizzare uno script in piccoli blocchi da eseguire nel punto e nel momento giusto, così che i task non accumulino tempo di blocco.
Il posto giusto per l'esecuzione di un task potrebbe anche essere fuori dal thread principale, in un worker.

Per fornire una buona esperienza utente, i siti dovrebbero cercare di mantenere il tempo di blocco totale inferiore a 300 millisecondi, se testati su un hardware mobile medio.
Il modo migliore per misurare il TBT è eseguire un audit delle prestazioni attraverso Lighthouse, prestando attenzione a tutte le opportunità suggerite.

Inoltre, i ChromeDevTools, al pannello "Performance", visualizzano i task (colorati in grigio), marchiandoli con dei triangoli (bandierine) rossi se sono lunghi (bottleneck ).
Clicca sul pulsante di ricaricamento per iniziare la profilazione che registrerà il caricamento della pagina.

tbt_tempo_di_blocco_totale

La presenza del triangolo rosso nella vista del thread principale ("Main") significa che potrebbe esserci un problema relativo all'evento contrassegnato.
Passando il mouse su una barra ne scoprirai la durata e se è stato considerato "lungo".
Le schede sottostanti "Summary" (riepilogo) e "Bottom-Up" (dal basso verso l'alto) mostreranno quali task hanno contribuito maggiormente all'attività, facendole impiegare un tempo eccessivo per il completamento, compreso un link che permette di saltare alla riga pertinente nel codice sorgente responsabile del funzionamento del task.

9.

Visualizzazione dei contenuti più grandi

La metrica Largest Contentful Paint indica il momento in cui vengono visualizzati sullo schermo il testo o l'immagine più grandi nella viewport, ovvero i contenuti principali della pagina.
A tal proposito, il W3C e Google hanno convenuto che un metodo accurato per misurare i tempi di caricamento del contenuto principale di una pagina è quello, appunto, di intercettare il momento in cui viene visualizzato l'elemento più grande della viewport.

Per fornire una buona esperienza utente, la metrica in questione non dovrebbe sforare i 2,5 secondi dall'inizio del caricamento della pagina.

I tipi di elementi presi in considerazione dalla metrica sono:

La dimensione dell'elemento considerata per misurare LCP è quella visibile all'utente all'interno della finestra.
Se l'elemento si estende al di fuori della viewport, se viene troncato o presenta un overflow non visibile, tali porzioni non contano ai fini della determinazione della dimensione.

Per quanto riguarda le immagini che sono state ridimensionate rispetto alle loro misure originarie, se vengono ridotte a dimensioni molto inferiori rispetto a quelle di partenza, conteranno solo le dimensioni finali che andremo a visualizzare, mentre per le immagini allungate o espanse a dimensioni maggiori conteranno le loro dimensioni intrinseche.

Per quanto concerne gli elementi di testo viene considerata la dimensione del rettangolo che li racchiude, esclusi margini, riempimenti o bordi applicati tramite CSS, esclusione che vale anche per le immagini.

LCP può essere misurato in laboratorio o sul campo grazie a strumenti quali PageSpeed ​​Insights, i Chrome DevTools, Lighthouse, così come attraverso JavaScript con Largest Contentful Paint API, uno script che rimane in ascolto dei contenuti in ingresso per poi registrare il valore LCP sulla console.

In molti siti web le immagini rappresentano l'elemento più grande visualizzato al termine del caricamento della pagina.
Migliorare il tempo necessario al loro rendering inciderà favorevolmente sul punteggio LCP.
Ne parliamo in Codifica in modo efficace le immagini e Pubblica immagini in formati più recenti.

A volte, risorse importanti dichiarate o utilizzate in un determinato file CSS o JavaScript possono essere recuperate più tardi di quanto desiderato.
Se ritieni che una particolare risorsa debba avere la priorità (ad esempio, un font), potresti ricorrere al precaricamento per recuperarla il prima possibile.
A partire da Chrome 73, il precaricamento può essere utilizzato insieme alle immagini reattive per combinare entrambi i modelli e ottenere un caricamento delle immagini molto più veloce.
Ne parliamo in Precarica le richieste fondamentali e Usa immagini di dimensioni adeguate.

Gli algoritmi di compressione possono ridurre significativamente le dimensioni dei file di testo mentre vengono trasferiti tra il server e il browser, migliorando i tempi di caricamento e di conseguenza l'LCP.
Ne parliamo in Attiva la compressione del testo.

10.

Variazione layout cumulativa

La variazione layout cumulativa (Cumulative Layout Shift ) è una metrica incentrata sull'utente che aiuta a misurare la stabilità visiva, ovvero a quantificare la frequenza con cui gli utenti riscontrano cambiamenti di layout imprevisti: un CLS basso garantisce che la pagina sia piacevole da navigare.

Sarà capitato a chiunque di riscontrare cambiamenti improvvisi durante la navigazione di una pagina (ad esempio, stai per toccare un pulsante e, nell'istante prima del tocco, questo si sposta, finendo per fare clic su qualcos'altro).
Queste esperienze sono molto fastidiose, e solitamente si verificano perché le risorse vengono caricate in modo asincrono oppure gli elementi del DOM vengono aggiunti dinamicamente alla pagina sopra un contenuto già esistente.
Potrebbe trattarsi di un'immagine dalle dimensioni sconosciute, come di un annuncio di terze parti che si ridimensiona in maniera imprevista; in quest'ultimo caso una buona idea potrebbe essere quella di applicare uno stile al contenitore che ospiterà l'annuncio prima che questo venga caricato dalla libreria di terze parti, cossiché il contenuto incorporato possa adattarsi allo spazio riservatogli.
Ciò che rende questo problema ancora più fastidioso è che il modo in cui un sito funziona in fase di sviluppo è spesso molto diverso da come lo sperimentano gli utenti; le immagini sono spesso già nella cache del browser dello sviluppatore e le chiamate API eseguite localmente sono spesso così veloci che il ritardo non è evidente.

Le variazioni si verificano solo quando gli elementi esistenti cambiano la loro posizione iniziale.
Se un nuovo elemento viene aggiunto al DOM o un elemento esistente cambia dimensione non viene considerato come uno spostamento del layout a condizione che la modifica non porti altri elementi visibili a cambiare la loro posizione iniziale.

cumulative_layout_shift_example

Per calcolare il punteggio di spostamento del layout il browser esamina il movimento degli elementi instabili e le dimensioni della finestra che li contiene (la viewport) tra due fotogrammi renderizzati.
Il punteggio è il prodotto di due misure di quel movimento: la frazione di impatto e la frazione di distanza.
Spieghiamole con un esempio.

frazione_di_impatto_frazione_di_distanza

A sinistra dell'immagine sopra un elemento occupa metà della viewport.
A destra lo stesso elemento si sposta verso il basso del 25%.
Il rettangolo rosso tratteggiato indica l'area occupata dallo stesso elemento in fotogrammi differenti che, nell'immagine d'esempio, corrisponde al 75% della viewport, quindi la frazione d'impatto del fotogramma corrente è 0,75.

La frazione di distanza misura di quanto un elemento si sia spostato rispetto alla viewport.
Nell'esempio precedente l'elemento preso in esame si è spostato del 25% dell'altezza della viewport (freccia viola), sicché la sua frazione di distanza equivale a 0,25.

Il punteggio di spostamento del layout sarà 0,75 * 0,25 = 0,1875.

I cambiamenti dinamici applicati a una pagina o applicazione web modificano frequentemente la posizione iniziale degli elementi, ma non tutte le variazioni del layout hanno effetti negativi; sono da considerarsi tali solo se l'utente non se li aspetta.
Quando si verificano in risposta alle interazioni dell'utente (clic su un collegamento, pressione di un pulsante, digitazione in una casella di ricerca) vanno generalmente bene purché lo spostamento si verifichi abbastanza vicino all'interazione.
Ad esempio, se un'interazione attiva una richiesta di rete che potrebbe richiedere del tempo per essere completata è meglio creare subito un pò di spazio e mostrare un indicatore di caricamento per evitare un inatteso spostamento del layout al completamento della richiesta.
Se l'utente non si rende conto che qualcosa si sta caricando o non ha contezza di quando la risorsa sarà pronta può provare a fare clic su qualcos'altro durante l'attesa, correndo il rischio di generare variazioni sgradevoli per l'esperienza utente.

Le animazioni e le transizioni, se eseguite correttamente, sono un ottimo modo per aggiornare i contenuti della pagina senza sorprendere l'utente.
Il contenuto che si sposta bruscamente e inaspettatamente crea quasi sempre un'esperienza utente negativa.
Invece, spostandolo gradualmente e naturalmente da una posizione all'altra può aiutare l'utente a capire meglio cosa sta succedendo e guidarlo tra i cambiamenti di stato.

CLS può essere misurato in laboratorio o sul campo attraverso PageSpeed ​​Insights, Search Console, i Chrome DevTools, Lighthouse, come anche mediante la libreria JavaScript "web-vitals", il cui pattern si mette in ascolto delle singole variazioni di layout verificatesi, registrandole nella console.

E` possibile evitare cambiamenti imprevisti del layout attenendosi ad alcuni principi guida come dichiarare sempre le dimensioni delle immagini (come anche degli elementi <video> e degli <iframe>) affinché il browser possa allocare la quantità corretta di spazio nel documento durante il caricamento dell'immagine.

width_height_attributes_html

Seguito l'esempio in immagine ci penserà il browser ad aggiungere un aspect-ratio (rapporto tra larghezza e altezza) basato sugli attributi di larghezza e altezza dell'elemento prima che l'immagine sia caricata.
Il valore auto assegnato alla proprietà height attraverso i CSS evita che l'altezza dell'immagine assuma un valore fisso.

Limitarsi solamente a dare auto alla height dell'immagine attraverso i CSS è un approccio che, per quanto responsive, presenta lo svantaggio che lo spazio riservato all'immagine potrà essere allocato solo una volta che il browser ne ha iniziato il download.
Immaginiamo di avere un menu di argomenti composto da ancore e delle immagini che verranno caricate lentamente (vedi giù, Rimanda immagini fuori schermo).
Cliccando su un ancora salteremo all'argomento di nostro interesse.
Al click sull'ancora, il browser non conosce ancora le dimensioni delle immagini che incontrerà e neanche l'altezza che il layout andrà ad assumere una volta caricate.
Durante il salto, il browser comincerà a scaricare le immagini, per cui le dimensioni del layout cambieranno, tuttavia l'utente potrebbe essere riportato in un punto differente da quello desiderato, proprio perché nel frattempo le immagini sono state aggiunte alla pagina, modificandone l'altezza.
Tutto ciò rischia di confondere l'utente, rendendo sgradevole la UX.

11.

Usa immagini di dimensioni adeguate

La sezione "Opportunità" del rapporto Lighthouse elenca tutte le immagini della tua pagina che non sono dimensionate in modo appropriato, insieme ai potenziali risparmi in kilobyte (KB); ridimensionarle ne migliorarerà i tempi di caricamento.

usa-immagini-di-dimensioni-adeguate

Per ogni immagine sulla pagina vengono confrontate la dimensione dell'immagine renderizzata con quella effettiva; se la dimensione del rendering è inferiore di almeno 25 KB rispetto alla dimensione effettiva l'immagine non supera il controllo.
Le immagini non andrebbero pubblicate più grandi della versione visualizzata sullo schermo dell'utente, perché questo comporta solo byte sprecati e rallenta il tempo di caricamento della pagina (la pubblicazione di immagini di dimensioni desktop su dispositivi mobili può utilizzare da 2 a 4 volte più dati del necessario).
L'immagine sembra a posto perché una qualche regola CSS ne starà adattando le misure alle dimensioni della pagina; il prezzo, spesso, è uno spreco di banda degli utenti e un peggioramento delle prestazioni.

Una soluzione potrebbe essere quella di servire immagini di dimensioni adeguate ("immagini reattive"), ovvero generare più versioni di ciascuna immagine, specificando (nel proprio HTML o utilizzando le query multimediali CSS) quale di queste verrà utilizzata a seconda delle condizioni di contesto; oppure ricorrere a formati di immagini vettoriali, come SVG, riadattabili a qualsiasi dimensione di schermo.

Quanto alla prima soluzione, è comune servire 3-5 diverse dimensioni di un'immagine, anche se non esiste un numero corretto; tuttavia, è vero che le prestazioni miglioreranno ma nello stesso tempo verrà occupato maggiore spazio sui server, oltre a dover scrivere un pò più di HTML.
Una volta specificate le diverse versioni il browser sceglierà la migliore da utilizzare.

Gli attributi src, srcset e size del tag <img> interagiscono tutti per raggiungere il risultato finale.

src-srcset-size

L'attributo src fa funzionare il codice di esempio per i browser che non supportano gli attributi srcset e size; in tale ipotesi, il browser caricherà la risorsa specificata dall'attributo src, che dovrà essere abbastanza grande da funzionare bene su tutte le dimensioni assumibili dal dispositivo.

L'attributo srcset contiene un elenco separato da virgole di nomi di file immagine e dichiarazioni della loro larghezza; in questo modo il browser viene a conoscenza anticipatamente della larghezza di un'immagine, evitando di doverla scaricare per determinarne le dimensioni.
Utilizzare l'unità w (corrispondente a px) per dichiarare la larghezza.

L'attributo size indica al browser la larghezza dell'immagine quando verrà visualizzata.
Lo user agent utilizza tale dimensione, dividendola per i descrittori di larghezza specificati nell'attributo srcset, per calcolare la densità effettiva dei pixel.
Il browser si serve di queste informazioni, insieme a ciò che conosce sul dispositivo dell'utente (ad esempio le misure della viewport) per selezionare la più adeguata (in termini di dimensioni) delle immagini fornite dall'attributo srcset.
La dimensione può essere specificata usando una varietà di unità, assolute e relative (px, em, vw), ad esclusione della percentuale.
Se il browser non riconosce l'attributo size tornerà al caricamento dell'immagine specificata dall'attributo src.

Un altro approccio altrettanto flessibile prevede il ricorso al tag HTML5 <picture>, che fornisce un’immagine all’utente finale in modo variabile e dinamico in base alla verifica di determinate condizioni.
L’elemento <picture> contiene più elementi figli <source>, ognuno riferibile a dimensioni differenti della stessa immagine, cosicché il browser possa scegliere quale immagine caricare e mostrare in base alle attuali dimensioni del dispositivo che sta navigando la pagina, definite attraverso i breakpoints che possiamo impostare grazie all'attributo HTML media applicato al tag <source>.

usa-immagini-di-dimensioni-adeguate

E` bene non dimenticare di inserire un tag <img> come ultimo figlio dell’elemento picture, che verrà utilizzato nel caso in cui il browser non supporti il tag picture, o nel caso in cui nessuna delle media query venga soddisfatta.

12.

Codifica in modo efficace le immagini

La sezione "Opportunità" raccoglie tutte le immagini sulla pagina e imposta il livello di compressione di ciascuna di esse su 85, quindi confronta la versione originale con la versione compressa; se i potenziali risparmi sono di 4KB o superiori, Lighthouse contrassegna le immagini come ottimizzabili, con l'obiettivo di velocizzare il caricamento della pagina e consumare meno dati.
Le immagini non compresse "gonfiano" inultilmente le pagine, causando uno spreco di byte non necessari.

codifica-in-modo-efficace-le-immagini

La compressione è il metodo principale per ridurre le dimensioni delle immagini, e quando vengono allegerite significativamente senza (al contempo) sacrificarne la qualità allora la codifica potrà ritenersi efficace.
Innumerevoli tools online possono aiutarvi in questo compito (ad es. Compressor.io ).

Dunque, lo scopo della compressione è trovare il giusto compromesso tra la minore dimensione raggiungibile dall'immagine e una qualità soddisfacente.
A questo proposito, esistono due tipi di compressione utilizzabili, con perdita (Lossy ) e senza perdita di dati (Lossless ).
Il primo è un filtro che elimina una parte dei dati dell'immagine, riducendone le dimensioni con possibile diminuzione della resa qualitativa, mentre il secondo comprime i dati senza perdità di qualità.
E` bene fare esperimenti con ciascuna tecnica di compressione, anche se molti degli strumenti e software pensati a tale scopo offrono regolazioni di qualità già correttamente preimpostate per arrivare ad ottenere una compressione ottimale.

13.

Pubblica immagini in formati più recenti

PageSpeed Insights raccoglie ogni immagine BMP, JPEG e PNG sulla pagina, quindi le converte mostrando i potenziali risparmi ottenuti servendole con formati aventi caratteristiche di compressione e qualità superiori rispetto alle loro controparti (JPEG 2000, JPEG XR, WebP ).
Lighthouse omette l'immagine dal suo rapporto se il risparmio ottenibile è inferiore a 8 KB.
La codifica delle immagini in questi formati determinerà un caricamento più veloce e un minor consumo di dati.

pubblica-immagini-in-formati-più-recenti

In particolare WebP è un eccellente sostituto di immagini JPEG e PNG, offrendo una compressione sia lossless che lossy e portando a una riduzione delle dimensioni del file sull'entità del 25–35%.

I tag <picture>, <source> e <img>, incluso il modo in cui sono ordinati l'uno rispetto all'altro, interagiscono tutti per raggiungere lo stesso risultato.

pubblica-immagini-in-formati-più-recenti

<picture> fornisce un wrapper (contenitore) per uno o più tag <source> (che specifica la risorsa multimediale preferita, elencata per prima) e il tag <img>.
Quanto al valore dell'attributo type dovrebbe essere il tipo MIME corrispondente al formato dell'immagine. Il tipo MIME di un'immagine e la sua estensione sono spesso simili, ma non sono necessariamente la stessa cosa (ad es. jpg e image/jpeg).
Il browser utilizza la prima fonte elencata avente un formato riconosciuto; in caso di mancato supporto dei formati presenti nei tag <source> questi verrano ignorati dal browser che "vedrà" solo il tag <img> (lasciato per ultimo) e caricherà l'immagine di fallback (di ripiego) inclusa al suo interno e dall'estensione universalmente supportata.

14.

Rimanda immagini fuori schermo

Secondo alcune statistiche, le immagini sono il tipo di risorsa più richiesto per la maggior parte dei siti web e di solito occupano più larghezza di banda rispetto a qualsiasi altra risorsa (i siti inviano circa 4,7 MB diimmagini su desktop e dispositivi mobili).

La sezione Opportunità di PSI elenca tutte le immagini fuori schermo nella pagina, delle quali andrebbe preso in considerazione il caricamento lento (lazy loading ) dopo che tutte le risorse critiche (above the fold, visualizzabili senza scorrimento) hanno terminato il caricamento, col fine di ridurre il peso della pagina iniziale e il tempo di visualizzazione dei primi contenuti.

Il lazy loading è un approccio che deferisce il caricamento delle risorse fino a quando non sono necessarie, anziché caricarle in anticipo, allo scopo di migliorare le prestazioni attraverso la riduzione della quantità di risorse che devono essere caricate e analizzate durante il rendering (visualizzazione) dei contenuti iniziali della pagina.
Le immagini fuori schermo (ovvero quelle che si trovano al di sotto della vista del dispositivo) durante il pageload iniziale sono le candidate ideali per questa tecnica, che ne permette il recupero solo quando l'utente scorre vicino ad esse.

lazy-loading-immagini

L'adozione del lazy loading è una best practice per la UX giustificata da motivi tutt'altro che secondari.
E` verosimile infatti pensare che il browser dell'utente vada a caricare elementi che quest'ultimo potrebbe non vedere mai.
Considerando che, ad oggi, una grossa fetta delle connessioni al Web avviene attraverso piani dati limitati (riferibili alla telefonia mobile), caricare materiale che l'utente potrebbe effettivamente non visualizzare costituirebbe uno spreco in termini di larghezza di banda (che potrebbe essere sfruttata per scaricare altre risorse), oltre che di denaro.
Senza dimenticare lo spreco di tempo necessario al processamento, il consumo di batteria e di tante altre risorse di sistema in quanto, dopo aver scaricato una risorsa, il browser deve decodificarla e renderizzarne il contenuto nella finestra.

Per evitare che il contenuto circostante venga ridisposto quando viene scaricata un'immagine fuori schermo, assicurarsi di aggiungere gli attributi di altezza e larghezza all'elemento <img>; le immagini verranno comunque caricate "lentamente" se le dimensioni non sono incluse, ma specificandole si riduce la possibilità di ridisposizione da parte del browser.

Il lazy loading è supportato direttamente da alcuni browser (Chrome 76, Mozilla Firefox 75) grazie al nuovo attributo nativo loading, al quale va assegnato il valore lazy ; ciò potrebbe non rendere strettamente necessaria la presenza di una libreria esterna, garantendone il funzionamento anche qualora JavaScript fosse disabilitato sul client.
Tuttavia, è importante continuare a utilizzare una libreria di terze parti insieme all'attributo per fornire un polyfill ai browser che l'attributo non lo supportano ancora.

lazysizes è una popolare libreria JavaScript di lazy loading che il browser andrà a caricare come fallback solo quando l'attributo nativo non viene riconosciuto.

lazy-loading-immagini

Va aggiunta la classe lazyload per indicare alla libreria di quali immagini dovrà differire il caricamento e l'attributo src andrà modificato in data-src. Perché?
Perché non è un attributo riconosciuto dal browser, quindi quando quest'ultimo incontra un immagine che lo contiene non la caricherà, attendendo l'intervento dell'attributo loading o lasciando decidere alla libreria quando caricare l'immagine.

Per testare il funzionamento della strategia, aprire la scheda "Network" nei Chrome DevTools (strumenti per sviluppatori), filtrare le sole immagini e iniziare a scorrere la pagina; ognuna delle immagini contenenti l'attributo e la classe verrà caricata in prossimità del suo ingresso in schermo.

Le immagini definite utilizzando l'elemento <picture> possono anch'esse essere caricate in modo lento, ma ciononostante l'attributo che ne deferirà il caricamento deve essere incluso solo nell'elemento <img> di fallback.

L'attributo loading non può essere sfruttato con le immagini di sfondo CSS (background-image ); allo stato attuale può essere utilizzato solo dentro il tag <img>.

Come per le immagini, anche per i video fuori schermo può essere rimandato il caricamento.

lazy-loading-video

Se la sorgente video è un file univoco ospitato su un server web, implementando l'attributo preload sull'elemento <video> suggerisci al browser il recupero della risorsa multimediale solo quando il documento HTML iniziale è stato completamente caricato ed analizzato.
Così facendo, se i video non fanno parte dell'esperienza utente principale, la velocità della pagina può anche migliorare, dato che l'attributo impedisce un possibile recupero ritardato delle risorse critiche causato, appunto, dal caricamento della risorsa multimediale.

Utilizzare l'attributo poster per assegnare al video un'immagine d'anteprima (placeholder ).

15.

Assicurati che il testo rimanga visibile durante il caricamento dei caratteri web

I web fonts sono dei file che offrono agli sviluppatori la possibilità di incorporare una ricca tipografia nei loro progetti, permettendo di personalizzare la formattazione del testo.
Possono assumere grandi dimensioni e richiedere tempo per essere scaricati, motivo per cui alcuni browser (anche a causa della latenza delle reti) nascondono il testo fino al completamento del download del font, provocando una sorta di "lampo" che influenza negativamente l'esperienza utente; d'altronde, a nessuno importa quanto sia bello il font che utilizzi se ci vuole una quantità eccessiva di tempo affinché venga visualizzato.

Decidere il comportamento di un web font durante il caricamento può essere un'importante tecnica di ottimizzazione delle prestazioni.

font-display-css

Proprio per questo, è stata introdotta una nuova proprietà CSS (font-display ) che consente di specificare una strategia di visualizzazione dei caratteri in grado di controllare il rendering di un font prima che questo sia completamente scaricato.

font-display segmenta la durata del download di un carattere in tre periodi e supporta determinati valori.

I primi due periodi sono conosciuti come periodo di blocco e periodo di scambio dei caratteri, durante i quali se il font non viene caricato, qualsiasi elemento che tenta di utilizzarlo deve eseguire il rendering del carattere con un font di fallback, mentre se il font viene caricato correttamente ne conseguirà il suo normale utilizzo.

Il terzo periodo è conosciuto come periodo di errore, che si verifica immediatamente dopo il periodo di scambio, pertanto se il font non è ancora stato caricato all'inizio del periodo di scambio viene contrassegnato come caricamento non riuscito, causando il ricorso al carattere di fallback.

font-display

Quanto ai valori assumibili dalla font-display, menzioniamo:

Sempre in tema di performances, qualche considerazione aggiuntiva la merita il tipo di font adottabile.
A questo proposito, WOFF (Web Open Font Format) è un formato di font web sviluppato da Mozilla (in collaborazione con altre organizzazioni) la cui adozione presenta una serie di vantaggi, in primis l'ampio supporto da parte dei browser che lo rende veramente universale e amato dai progettisti web.
Inoltre, i dati del carattere sono compressi di default, quindi i siti web che lo adottano utilizzeranno meno larghezza di banda e lo scaricheranno più velocemente rispetto a file equivalenti non compressi.

16.

Pubblica le risorse statiche con criteri della cache efficaci

Quando il client richiede una risorsa, il server che la fornisce può specificare al browser per quanto tempo dovrà archiviarla nella cache.
Per qualsiasi richiesta successiva di quella risorsa, il browser utilizza la sua copia locale anziché ottenerla dalla rete, facendone conseguire una possibile accellerazione dei tempi di caricamento della pagina durante le visite ripetute.

pubblica-le-risorse-statiche-con-criteri-della-cache-efficaci

Lighthouse contrassegna come statiche e memorizzabili nella cache risorse quali font, immagini, file multimediali, script, fogli di stile delle quali, una volta falliti i controlli, vengono elencati i risultati in una tabella a tre colonne:

  1. URL. La posizione della risorsa memorizzabile nella cache;
  2. Cache TTL. La durata della cache corrente della risorsa;
  3. Dimensione. Una stima dei dati risparmiati dagli utenti se la risorsa contrassegnata fosse stata memorizzata nella cache.

I dettagli specifici su come configurare la durata della cache variano a seconda del server web utilizzato, pertanto è necessario consultare le documentazioni pertinenti e relative alla configurazione del file .htaccess (Apache, nginx), solitamente già presente nella root (la cartella madre) del proprio spazio hosting.

Esistono due scenari importanti da considerare durante la configurazione delle intestazioni di risposta del server web.
1. Richieste di URL che contengono informazioni il cui contenuto non è destinato a cambiare.

Cache-Control: max-age=31536000

L'impostazione del valore in esempio indica al browser che quando dovrà caricare le risorse alle quali il settaggio fa riferimento, in qualsiasi momento, nel prossimo anno (il valore massimo supportato, 60 secondi × 60 minuti × 24 ore × 365 giorni = 31536000 secondi), può immediatamente utilizzare quelle già salvate nella cache HTTP locale, senza dover effettuare una nuova richiesta di rete al server web.

2. Ricorso alla direttiva no cache quando il contenuto delle risorse cambia di frequente, ovvero quando l'aggiornamento e la novità costituiscono un tratto distintivo importante del sito web.

Cache-Control: no-cache

Nel secondo scenario è comunque possibile ottenere alcuni dei vantaggi della velocità della cache, in quanto il browser memorizza anche la risorsa impostata su no-cache ma non prima di aver interagito con il server per verificare che la risorsa corrente e quella memorizzata coincidano.

Una durata della cache più lunga non è sempre la scelta migliore; sta al webmaster decidere se e quale sia la sua durata ottimale per conservare le singole risorse.

Per vedere quali risorse il browser sta recuperando dalla sua cache, aprire la scheda "Network" nei Chrome DevTools (strumenti per sviluppatori) e ispezionare la colonna "Size".

pubblica-le-risorse-statiche-con-criteri-della-cache-efficaci

Per verificare che l'intestazione Cache-Control di una risorsa sia impostata come previsto, cliccare sull'URL della risorsa, sotto la colonna "Name", e poi sulla scheda "Headers".

cache-policy-htaccess
17.

Elimina le risorse di blocco della visualizzazione

La sezione Opportunità del rapporto Lighthouse elenca tutti gli URL che ritardano la visualizzazione dei primi contenuti di una pagina, con l'obiettivo di ridurre il loro impatto sul rendering delle risorse critiche.

Quando ci si collega ad una pagina web il browser richiede il documento HTML a un server, analizza il suo contenuto e invia richieste separate per qualsiasi risorsa collegata.
I fogli di stile (come anche gli script) sono tra quelle risorse che possono contenere regole inizialmente non necessarie per il caricamento dei contenuti above the fold, costringendo il browser ad attendere l'elaborazione di tutto il foglio prima di iniziare a decorare ogni singolo pixel.
Se il file CSS è grande o le condizioni di rete sono scarse, i tempi necessari al caricamento possono aumentare sensibilmente.
Ottimizzando il percorso di rendering critico è possibile migliorare in modo significativo le performance di una pagina web, aumentando il coinvolgimento degli utenti e le loro visualizzazioni.

Il primo passo per ridurre l'incidenza delle risorse di blocco del rendering è distringuere ciò che è critico da ciò che non lo è, consultando la scheda "Coverage" del pannello "Sources" in Chrome DevTools.
Per accedere alla scheda "Coverage" degli strumenti di sviluppo, dirigersi al menu (a 3 puntini) in alto a destra, poi "Run Command" e selezionare "Show Coverage", infine clic sul pulsante "Ricarica" per iniziare il rilevamento.

elimina-le-risorse-di-blocco-della-visualizzazione

Quando viene caricata una pagina la scheda indica quanto codice è stato utilizzato rispetto a quanto ne è stato caricato.
Dall'ispezione dell'URL (cliccandoci sopra) emergeranno gli stili necessari per la visualizzazione dei primi contenuti della pagina (critici), contrassegnati da una linea verde (o azzurra), e gli stili che si applicano ai contenuti non immediatamente visibili (non critici), contrassegnati da una linea rossa.

Una prima soluzione per eliminare gli stili che bloccano il primo rendering potrebbe essere quella di incorporare le regole riferite ai contenuti critici all'interno del tag <style> (dentro la <head>, all'inizio del documento html) caricando gli stili rimanenti in maniera collegata (con il tag <link>) e asincrona.
Tale approccio divide il CSS in due parti; quello critico, richiesto per il rendering del contenuti above the fold, viene inserito dentro il tag style, quello non critico viene memorizzato nella cache del browser prima che il file che lo contiene sia stato scaricato, in modo che sia immediatamente disponibile quando necessario, separando così il recupero del codice dalla sua esecuzione.
In altre parole, il CSS non critico viene archiviato localmente nel browser e rimarrà, effettivamente, inerte fino a quando non verrà richiamato.

elimina-le-risorse-di-blocco-della-visualizzazione

prefetch può essere utilizzato per effettuare la richiesta di un percorso di navigazione con una priorità inferiore rispetto ad altri asset più importanti.

Il precaricamento (prefetch, l'attributo preload lo vedremo più avanti) è supportato in tutti i browser moderni, ad eccezione di Firefox.
Fornire l'attributo as aiuta il browser a impostare la priorità della risorsa precaricata in base al suo tipo e determinare se questa esiste già nella cache.
I valori accettati per questo attributo includono script, style, font, image.
Omettere l'attributo as o assegnarli un valore non valido impedisce al browser di sapere cosa sta recuperando, quindi non può determinare la priorità corretta, causando un possibile e inutile doppio recupero di alcune risorse.

Tuttavia, l'approccio in questione presenta anche alcuni svantaggi.
Anzitutto non esiste un'altezza di pixel definita universalmente che identifichi tutto ciò che possa considerarsi contenuto above the fold, poiché esiste una gran moltitudine di dispositivi in commercio, ognuna con dimensioni di schermo e viewport peculiari.
In secondo, l'approccio inline impedisce al browser di memorizzare nella cache il CSS critico per riutilizzarlo ai successivi caricamenti della pagina.

Esistono numerosi strumenti che possono determinare automaticamente il CSS critico per una pagina e funzionano bene su tutti i browser; farlo manualmente richiede un'analisi dell'intero DOM per determinare gli stili applicati a ciascun elemento e sarebbe un processo lungo e noioso.
Uno di questi è Critical.
Disponibile come modulo npm, estrae, minimizza e incorpora i CSS above the fold critici, non necessita di specificare i fogli di stile, venendo rilevati automaticamente, e supporta anche l'estrazione di CSS critici per risoluzioni multiple dello schermo.

Una seconda soluzione per eliminare gli stili di blocco del rendering è quella di suddividere tali stili in file diversi, aggiungendo un attributo multimediale (media) a ciascun collegamento ai fogli di stile, attraverso il quale vengono specificate le coordinate del dispositivo al quale il foglio verrà applicato; al caricamento della pagina il browser recupererà solo il foglio la cui media query corrisponde alle specifiche del dispositivo dal quale proviene la connessione.
Dunque, grazie alle media query possiamo rendere il CSS risorsa non bloccante e fornirlo più rapidamente per sbloccare il rendering.

media-query

Con le media query lo stile di una pagina può essere adattato all'uso specifico (per la stampa invece del monitor) o a condizioni dinamiche quali possono essere il ridimensionamento della viewport e i cambiamenti nell'orientamento dello schermo.
A questo proposito, è bene adottare un approccio fluido per l'impaginazione del layout, ricorrendo a specifiche quali flexbox o grid layout, che permettano agli elementi della pagina di essere adattivi sin dal principio, ricorrendo alle media query solo per adeguamenti indispensabili.

18.

Minimizza CSS e JavaScript

I file CSS e JavaScript possono contenere caratteri non necessari, come commenti, spazi bianchi, rientri.
In fase di produzione uno stile di scrittura troppo compatto va a discapito della leggibilità, fattore da preferire specie in presenza di codice articolato, dove una struttura ordinata favorisce un maggiore e migliore controllo di snippet e blocchi costituenti i vari file.
In fase di pubblicazione invece tutti i caratteri non essenziali possono essere rimossi in modo sicuro, riducendo le dimensioni del file senza influire sul modo in cui il browser andrà ad elaborarli: questa tecnica si chiama minificazione

Esistono numerosi tools, online o sotto forma di plugin, ai quali è possibile ricorrere per automatizzare il processo di snellimento delle risorse desiderate, al termine del quale disporremo di un codice più piccolo ma perfettamente valido, che contribuirà a migliorare i tempi di caricamento della pagina.

Il più delle volte, alla minificazione si può ricorrere anche attraverso i propri editor di codice mediante i settaggi per la rimozione degli spazi non necessari.
E` un'operazione da non sottovalutare considerato che la dimensione dei file (fogli di stile, script) può andare incontro a riduzioni significative, anche di oltre il 25%.

19.

Evita payload di rete enormi

L'espressione payload può assumere diversi significati, a seconda del contesto.
Nel nostro scenario si riferisce ai dati trasmessi, che rappresentano il contenuto informativo destinato all'utilizzatore finale (l'utente).
Le risorse oggetto dello scambio vengono trasportate attraverso la banda, ovvero i byte necessari per inviare richieste e ottenere risposte attraverso la rete.

Payload di rete di grandi dimensioni sono correlati con lunghi tempi di caricamento e costi per gli utenti, i quali potrebbero dover pagare in base al consumo dei dati cellulari.

Lighthouse mostra la dimensione totale in kilobyte di tutte le risorse richieste dalla tua pagina, contrassegnando per prime le più esose, ovvero quelle che superano i 5.000 KB.
Un payload di rete medio dovrebbe essere compreso tra 1.700 e 1.900 KB, pertanto bisognerebbe cercare di mantenere la dimensione totale dei byte inferiore a 1.600 KB, obiettivo, questo, che si basa sulla quantità di dati che possono essere teoricamente scaricati su una connessione 3G mantenendo tempi di visualizzazione discretamente rapidi.

I metodi per ridurre le dimensioni del payload sono, per la maggior parte, quelli già analizzati:

20.

Evita un DOM di dimensioni eccessive

Un grande albero del DOM può rallentare le prestazioni della pagina in diversi modi.
Spesso include molti nodi che non sono visibili quando l'utente visualizza i primi contenuti, il che aumenta i tempi di caricamento.
Man mano che gli utenti e gli script interagiscono con la tua pagina il browser deve costantemente ricalcolare la posizione e lo stile dei nodi; tutto ciò, in combinazione con regole di stile complicate, può rallentare notevolmente il rendering.

evita-un-dom-di-dimensione-eccessive

Lighthouse riporta gli elementi DOM totali per una pagina, la profondità DOM massima e i suoi elementi figlio, contrassegnando le pagine che:

Oltre a consigliarvi di creare un nodo solo quando necessario, è possibile rimuovere i nodi non visualizzati inizialmente, al caricamento del documento, e generarli dinamicamente (attraverso JavaScript) solo dopo una interazione dell'utente pertinente, come uno scorrimento o un clic su un pulsante.

21.

Riduci il tempo di esecuzione di JavaScript

Si stima che oltre il 50% degli utenti abbandona un sito web se il caricamento richiede più di 3 secondi: a nessuno piace aspettare.

Lighthouse visualizza un controllo non riuscito quando viene impiegato un tempo significativo per eseguire il codice JavaScript su una pagina; mostra un avviso quando l'esecuzione richiede più di 2 secondi, restituisce esito negativo quando supera i 3,5 secondi.
A tal riguardo, l'invio di payload JavaScript di grandi dimensioni influisce notevolmente sulla velocità del tuo sito.

riduci-il-tempo-di-esecuzione-di-javascript

JavaScript viene analizzato e compilato sul thread principale; se la pagina esegue molto codice prima che sia realmente necessario, il thread rimane occupato fin quando tutto il codice non viene eseguito e la pagina (fino a quel momento) non potrà rispondere agli input dell'utente.
Tutto ciò ha anche i suoi costi in termini di memoria; un uso intensivo della CPU fa apparire le pagine irregolari o lente, sino a bloccarle completamente.

Per velocizzare l'esecuzione di JavaScript la soluzione è simile a quella considerata precedentemente per i fogli di stile ovvero, anziché spedire tutto il codice non appena viene caricata la pagina, dividerlo in più blocchi e inviare tramite il tag <script> quello responsabile del percorso iniziale, caricando in modo asincrono il codice che risulterà necessario all'utente solo in un secondo momento, mediante l'attributo defer, del quale descriviamo funzionamento e implementazione nel paragrafo successivo.

Altri possibili metodi per migliorare il caricamento della pagina li abbiamo già affrontati nei paragrafi precedenti, ovvero la minimizzazione del codice e la memorizzazione dello stesso nella cache.

22.

Limita il codice di terze parti

Per aggiungere un pulsante social media, un banner pubblicitario, la somministrazione di un test agli utenti o un servizio di analisi alla tua pagina potrebbe essere necessario integrare uno script di terze parti al tuo HTML.
Tali script aumentano la potenza di un sito in termini di funzionalità, rendendolo più dinamico e interattivo, ma possono influire in modo significativo sulla privacy, sulla sicurezza e sul comportamento delle pagine, risultando particolarmente problematici per le prestazioni di caricamento.

L'impostazione delle connessioni con risorse di terze parti richiede tempo e l'invio di troppe richieste a più server provoca rallentamenti.
Poiché il JavaScript di terze parti è, solitamente, al di fuori del tuo controllo, può causare ulteriori problemi, aggiungendosi al sovraccarico della rete con:

Se una terza parte ha problemi con il server e non riesce a consegnare una risorsa, il rendering viene bloccato fino al timeout della richiesta.
Durante il caricamento della pagina, Lighthouse calcola per quanto tempo ciascun codice di terze parti blocca il thread principale; se il tempo di blocco totale è superiore a 250 ms il controllo ha esito negativo.

L'uso di JavaScript di terze parti è spesso inevitabile, ma alcune scelte possono ridurre i suoi effetti avversi, vedi il favorire quelle risorse che inviano la minima quantità di codice pur offrendo le funzionalità necessarie alle nostre esigenze, come anche il non utilizzare la stessa funzionalità offerta da due diversi fornitori, ad esempio tag manager o piattaforme di analisi.

Alcune tecniche possono aiutarci a ottimizzare il processo di caricamento degli script di terze parti.
Tra queste vi è il ricorso agli attributi async o defer sul tag <script>, che possono velocizzare notevolmente il caricamento della pagina.

Quando il browser incontra uno script deve mettere in pausa la costruzione del DOM, consegnarlo al motore JavaScript e consentire l'esecuzione dello script; gli attributi che andiamo ad esaminare permettono di modificare questo comportamento.

Poiché gli script sincroni ritardano la costruzione e il rendering del DOM, è necessario caricare sempre script di terze parti in modo asincrono, a meno che l'esecuzione dello script non sia responsabile di operazioni legate al percorso di rendering critico.
Gli attributi in esame indicano al browser che potrebbe continuare ad analizzare l'HTML durante il caricamento dello script in background, quindi eseguire lo script dopo il caricamento; in questo modo i download degli script non bloccano la costruzione del DOM e il rendering, col risultato che l'utente può vedere la pagina prima che tutti gli script abbiano terminato il caricamento.
La differenza tra async e defer sta nel momento in cui gli script iniziano ad essere eseguiti.

async-defer

Quelli con l'attributo async vengono eseguiti alla prima opportunità al termine del download e prima dell'evento di caricamento della finestra.
Ciò significa che è possibile che gli script non vengano eseguiti nell'ordine in cui compaiono nell'HTML, come anche che possono interrompere la costruzione del DOM se terminano il download mentre il parser HTML è ancora al lavoro.
Utilizzare async se è importante che il codice di terze parti venga eseguito prima, nel processo di caricamento, come nel caso dell'inclusione degli script di analisi.

Quelli con l'attributo defer vengono eseguiti al termine dell'analisi HTML, ma prima dell'evento DOMContentLoaded.
defer ne garantisce l'esecuzione nell'ordine in cui compaiono nell'HTML, senza possibilità di blocco del parser.
L'utilizzo di defer è indicato per il caricamento di risorse meno critiche, come ad esempio un video situato below the fold.

Non caricare in modo asincrono o differito quegli script che costituiscono una parte cruciale delle funzionalità del tuo sito, come ad esempio librerie responsabili del funzionamento dell'esperienza utente.

Un'altra tecnica è quella di stabilire connessioni anticipate con origini di terze parti importanti.
Sono di aiuto a tale scopo gli attributi preconnect e dns-prefetch.

limita-il-codice-di-terze-parti

preconnect informa il browser che la tua pagina intende stabilire una connessione con un'altra origine e che desideri che il processo inizi il più presto possibile.
Quando viene effettuata la richiesta di una risorsa dall'origine precollegata il download inizia immediatamente.
E` bene preconnettersi solo a domini critici, che si andranno a utilizzere al più presto, perché il browser chiude qualsiasi connessione che non viene utilizzata entro 10 secondi.
La preconnessione può ritardare il caricamento di altre risorse importanti, quindi limitare il numero di domini preconnessi a quelli necessari.

Per i domini di terze parti meno critici, invece, utilizzare dns-prefetch, il cui supporto da parte dei browser è leggermente più esteso rispetto a preconnect, motivo per cui dns-prefetch potrebbe fungere da fallback per i browser che non supportano la preconnessione.

Utilizzare tag di collegamento separati per implementare le soluzioni in modo sicuro.

Un'altra tecnica (già presa in esame nei paragrafi antecedenti) è il caricamento lento delle risorse di terze parti incorporate, che possono rallentare la velocità della pagina.
Se non sono critiche o sono belove the fold (ovvero, se gli utenti devono scorrere per visualizzarle), grazie al caricamento lento quest'ultimi otterranno il contenuto iniziale della pagina più velocemente e avranno un'esperienza migliore.

Un'ulteriore tecnica è quella del self-hosting, ovvero ospitare sul proprio hosting il codice di terze parti, opzione che offre un maggiore controllo sul processo di caricamento di uno script terzo, ma che tuttavia presenta alcuni svantaggi, in quanto gli script gestiti autonomamente non riceveranno aggiornamenti automatici in caso di modifica dell'API o correzioni della sicurezza.

23.

Attiva la compressione del testo

La compressione del testo riduce al minimo la dimensione in byte delle risposte di rete che includono un contenuto testuale, e noi sappiamo già che meno byte scaricati significa un caricamento più veloce della pagina.

attiva-la-compressione-del-testo

Lighthouse raccoglie tutte le risposte di rete che contengono risorse basate su testo e che non includono un'intestazione di codifica del contenuto.
Quindi, comprime ciascuna di queste risorse con il formato GZIP (universalmente supportato in tutti i browser moderni) per calcolare i potenziali risparmi.
Se la dimensione originale di una risposta è inferiore a 1,4 KB o se il potenziale risparmio di compressione è inferiore al 10% della dimensione originale Lighthouse non contrassegna tale risposta nei risultati.

GZIP è applicabile a qualsiasi risorsa, ma risulta particolarmente efficace su quelle testuali, raggiungendo spesso un tasso di compressione del 70-90%.
La maggior parte dei server web comprime i contenuti per nostro conto pertanto, il più delle volte, bisogna solo verificare che il server sia configurato correttamente per comprimere tutti i contenuti che possano beneficiare della compressione con GZIP e fornirli quando il client li richiede.

Il progetto HTML5 Boilerplate contiene alcuni file di configurazione di esempio per tutti i principali server web (Apache, IIS, nginx), con commenti dettagliati per ogni impostazione.

Per vedere GZIP in azione, aprire i Chrome DevTools e controllare la colonna "Size" nella scheda "Network", recarsi sopra la risorsa desiderata, cliccare sulla scheda "Headers" e controllare l'intestazione della codifica del contenuto nella sezione "Response Headers".

attiva-la-compressione-del-testo
24.

Precollegati alle origini necessarie

La maggior parte del tempo per stabilire una connessione viene speso ad attendere piuttosto che a scambiare dati, comportando spesso tempi d'attesa significativi e latenza di rete.
Preoccuparsene in anticipo può rendere il tuo sito più scattante per l'utente senza influire negativamente sull'uso della larghezza di banda.

I browser moderni fanno del loro meglio per anticipare le connessioni necessarie per una pagina, ma non possono prevederle in modo affidabile.

Abbiamo già preso in esame l'attributo preconnect dell'elemento <link> (in Limita il codice di terze parti), col quale il browser viene informato che la tua pagina intende stabilire una connessione con un'altra origine e che desideri che il processo inizi il più presto possibile.

È possibile accelerare il tempo di caricamento di 100–500 ms stabilendo connessioni anticipate con origini di terze parti importanti, numeri che possono sembrare piccoli, ma che fanno la differenza nel modo in cui gli utenti percepiscono le prestazioni della pagina web.
In queste situazioni, se la risorsa che recupererai è importante, puoi risparmiare tempo pre-connettendoti al server e il browser non scaricherà il file fino a quando la tua pagina non lo richiede.

Un esempio in cui si potrebbe voler risparmiare del tempo nella fase di connessione, ma non necessariamente iniziare subito a recuperare il contenuto, è lo streaming di file multimediali da un'origine diversa.
La pre-connessione ti aiuta a ridurre i tempi di attesa per il recupero dei flussi multimediali da trasmettere quando il browser richiederà la risorsa.

Se una pagina deve effettuare connessioni a molti domini di terze parti preconnetterli tutti è controproducente.
La preconnessione è efficace solo per domini diversi da quello d'origine, e viene sfruttata al meglio solo per le connessioni più critiche; per tutto il resto ricorrere all'attributo dns-prefetch.

25.

Evita i reindirizzamenti tra più pagine

Quando un browser richiede una risorsa che è stata reindirizzata deve effettuare un'altra richiesta HTTP nella nuova posizione per recuperare la risorsa; questo ulteriore viaggio attraverso la rete attiva un nuovo ciclo di richiesta-risposta (roundtrip) che può ritardare il caricamento della risorsa e quindi intaccare la velocità di caricamento della pagina, che non supererà il controllo quando ha due o più reindirizzamenti.

evita-i-reindirizzamenti-tra-più-pagine

È particolarmente importante evitare i reindirizzamenti delle risorse necessarie per il tuo percorso di rendering critico; a tal proposito, se stai utilizzando i reindirizzamenti per deviare gli utenti mobile alla versione per smartphone e tablet della tua pagina prendi in considerazione di riprogettarla utilizzando un approccio responsivo.

Quanto detto non vale per i reindirizzamenti della pagina dalla versione http alla www e viceversa (da www ad http), fondamentali affinché i motori di ricerca non considerino l'una quale contenuto duplicato dell'altra.

26.

Precarica le richieste fondamentali

In uno dei paragrafi precedenti, parlando di precaricamento delle risorse avevamo fatto accenno alla presenza di un secondo attributo, ulteriore a prefetch : stiamo parlando di preload.

Per file importanti contenenti asset critici, necessari immediatamente non appena viene caricata la pagina, è possibile ricorrere all'attributo preload, che informa il browser di scaricare il file il prima possibile, eseguendo un prelievo preventivo della risorsa che si presuppone fondamentale per la pagina senza ritardarne il caricamento.

Se non utilizzato correttamente il precarico può danneggiare le prestazioni facendo richieste non necessarie per quelle risorse che non vengono utilizzate.
Chrome visualizza un avviso nel pannello "Console" quando una risorsa precaricata non viene utilizzata dalla pagina entro pochi secondi dal caricamento.

Gli elementi <link> accettano anche un attributo type, che contiene il tipo MIME della risorsa collegata.
I browser utilizzano il valore assegnatogli per assicurarsi che le risorse vengano precaricate solo se il loro tipo di file è supportato; se un browser non supporta il tipo di risorsa specificato ignorerà il precaricamento.

precarica-le-richieste-fondamentali

Per alcuni tipi di risorse, come i fonts, è necessario impostare l'attributo crossorigin : i caratteri precaricati senza tale attributo verranno recuperati due volte.

27.

Usa formati video per i contenuti animati

Se stai cercando di migliorare le prestazioni di caricamento del tuo sito e aiutare gli utenti a ridurre l'utilizzo dei dati, le GIF animate non sono compatibili con tale obiettivo.

La sezione Opportunità del rapporto Lighthouse elenca tutte le GIF animate presenti sulla tua pagina, insieme ai risparmi, stimati in secondi, ottenuti convertendo le GIF in video.

L'unico vero vantaggio dell'utilizzo della GIF animata rispetto al video è la praticità, dato che basta inserirne il riferimento in un elemento <img>.
Le GIF di grandi dimensioni tuttavia sono inefficienti per la consegna di contenuti animati, richiedendo un consumo considerevole in termini di CPU.
Convertendole in video riduci la quantità di dati che invii agli utenti e l'utilizzo delle loro risorse di sistema, risparmiando molto sulla larghezza di banda e salvando preziosi byte di rete.

Le GIF animate hanno tre tratti chiave che un video deve replicare:

Esistono diversi strumenti per convertire le GIF in video; FFmpeg è sicuramente uno dei più utilizzati.

Il formato video WebM è molto più piccolo rispetto al più noto MP4, ma non tutti i browser lo supportano, quindi è conveniente generare video per entrambe le estensioni dato che il tag <video> consente di specificare più elementi (figlio) <source> che puntano a diversi formati tra i quali il browser può scegliere, dentro i quali è possibile indicare una preferenza iniziale per la fonte WebM, che andranno ad utilizzare quei browser che supportano il formato, come anche una fonte MPEG-4 comprensibile a tutti gli altri browser.

Va precisato che i browser non decidono quale sia la risorsa ottimale da caricare, quindi l'ordine degli elementi <source> è importante. Ad esempio, se si specifica prima un video MPEG-4 e il browser supporta WebM, i browser salteranno il secondo e utilizzeranno il primo: pertanto, se preferisci dare priorità a una risorsa WebM specificalo prima.

usa-formati-video-per-i-contenuti-animati

Gli attributi in questo esempio sono piuttosto autoesplicativi.
Un elemento video che utilizza questi attributi verrà riprodotto automaticamente, ripetutamente (in loop), senza l'audio e in linea (ovvero, non a schermo intero).

28.

Riduci i tempi di risposta del server

Lighthouse riporta il tempo impiegato dal browser di un utente per ricevere dal server i primi bytes di contenuto della pagina.
Questo controllo fallisce quando il browser attende più di 600 ms affinché il server risponda alla richiesta.
Agli utenti non piace quando il caricamento delle pagine richiede molto tempo, e tempi di risposta del server lenti sono tra le possibili cause di lunghi caricamenti, che influiscono negativamente sulle prestazioni.
Più tempo impiega un browser per ricevere contenuti dal server, più tempo impiega per visualizzare sullo schermo ogni singolo elemento.

Un tempo di risposta del server più veloce influisce positivamente su ogni singola metrica di caricamento della pagina, riducendo il tempo che gli utenti trascorrono in attesa di poter navigare la pagina.

riduci-i-tempi-di-risposta-del-server

Esistono molte possibili cause di risposte lente del server e quindi molti modi possibili per migliorarle.

Anziché servire immediatamente una pagina statica su richiesta del browser, molti web framework lato server devono crearla in modo dinamico.
In altre parole, invece di inviare semplicemente un file HTML completo, quando il browser lo richiede, i framework devono eseguire la logica server-side per costruire la pagina.
Ciò potrebbe essere dovuto ai risultati in sospeso di una query al database particolarmente costosa, che richiede una notevole quantità di tempo per essere completata dal server.
A tal proposito, gli stessi framework possono contenere consigli su come ottimizzare la logica dell'applicazione lato server.
Si potrebbe anche prendere in considerazione di eseguire una migrazione a sistemi di database più veloci, oppure aggiornare l'hardware del proprio server per avere più memoria o CPU.

Altre operazioni complesse sul server possono ritardare il processo di restituzione del contenuto della pagina, ad esempio quando il markup HTML viene generato da un framework UI (come jQuery o React).

L'analisi e il miglioramento dell'efficienza del codice, e lato server e lato client, diminuirà il tempo necessario al browser per ricevere i dati.

Se il contenuto della tua pagina web è ospitato su un singolo server il tuo sito verrà caricato più lentamente per gli utenti che sono geograficamente più lontani, questo perché le richieste dei loro browser devono letteralmente viaggiare in tutto il mondo.
Potresti prendere in considerazione l'utilizzo di una rete CDN, ovvero una rete di server distribuiti in molti luoghi diversi, per assicurarti che le richieste di rete dei tuoi utenti non debbano mai attendere troppo a lungo.

Se il tuo codice HTML è statico e non deve essere modificato a ogni richiesta, la memorizzazione nella cache lato server può ridurre al minimo l'utilizzo delle risorse, evitando che il codice venga, di volta in volta, ricreato inutilmente.

Anche le richieste del server a origini di terze parti possono influire sui tempi di risposta, soprattutto se sono necessarie per visualizzare contenuti critici sulla pagina.
Ne parliamo in Limita il codice di terze parti

Prima che un browser possa eseguire il rendering di qualsiasi contenuto deve analizzare l'albero del DOM.
Il parser HTML si interrompe se incontra fogli di stile esterni o script sincroni, entrambi risorse di blocco del rendering che possono ritardare le risposte dal server.
E` bene rimandare qualsiasi JavaScript e CSS non critici per accelerare il caricamento del contenuto principale della tua pagina web.
Ne parliamo in Elimina le risorse di blocco della visualizzazione, Minimizza CSS e JavaScript, Riduci il tempo di esecuzione di JavaScript.

29.

Evita document.write

L'uso di document.write() (rispettivamente, proprietà e metodo dell'oggetto Window, che rappresenta una finestra aperta nel browser) per inserire script esterni in modo dinamico può ritardare di parecchi secondi la visualizzazione del contenuto della pagina ed è particolarmente problematico per gli utenti con connessioni lente, a tal punto che browser come Chrome possono bloccare le chiamate a document.write() o emettere un avviso in console, a seconda della velocità di connessione dell'utente.

Indipendentemente da come viene utilizzato, Lighthouse segnala tutte le chiamate a document.write(), vista l'influenza negativa sulle prestazioni e le alternative migliori al suo ricorso, tra cui il caricamento asincrono per iniettare script di terze parti.


Privacy Policy