Ottimizzare le prestazioni web è sempre stato fondamentale per siti web e app. Che si tratti di fornire servizi, intrattenimento o informazioni, le attività ne risentono quando le prestazioni sono lente o inconsistenti.
I siti di oggi hanno una maggiore sofisticatezza e più funzionalità che mai. Gli utenti si aspettano che tutto ciò funzioni senza problemi, ma se ciò non avviene, in un mercato competitivo, ci sono molte altre opzioni alternative. Quindi, cosa puoi fare per garantire che le prestazioni del tuo sito web rimangano all’avanguardia?
Cosa si intende con prestazione web?
La performance web è determinata da diversi fattori. Prendiamo in considerazione alcune delle metriche chiave.
- Tempo di caricamento: Probabilmente la metrica più basilare per la performance web, il tempo di caricamento misura il ritardo tra una richiesta iniziale di pagina e il contenuto visualizzato completamente nel browser. Spesso si ritiene che sia un fattore importante per il posizionamento nei motori di ricerca.
- First contentful paint (FCP): Far apparire qualcosa sullo schermo velocemente è un importante indicatore di progresso. L’FCP è una misura del tempo tra il caricamento iniziale e la resa di una parte del contenuto della pagina.
- Time to interactive (TTI): TTI misura il tempo tra l’FCP e il momento in cui la pagina diventa interattiva. Una pagina può sembrare completamente caricata, ma potrebbe essere necessario più tempo affinché i controlli diventino completamente interattivi. TTI è quindi una misura della reattività.
- Cumulative Layout Shift (CLS): Questa è una misura del momento in cui un layout di pagina diventa stabile. I layout delle pagine che si rimescolano durante il caricamento sono un’irritazione comune per gli utenti, in particolare con gli elementi interattivi. Pertanto, CLS è una metrica di usabilità chiave.
Ci sono altre metriche che potremmo prendere in considerazione, ma questo trio di velocità, reattività e usabilità fornisce un buon quadro di riferimento per considerare l’ottimizzazione. Con queste metriche in mente, esaminiamo le principali tecniche per migliorare le prestazioni.
Strategie per ottimizzare le prestazioni web
Code Splitting
Il code splitting consiste semplicemente nel suddividere il codice in componenti caricabili indipendentemente. Le applicazioni web di oggi spesso hanno un’impronta significativa in termini di CSS e Javascript. Tuttavia, non tutte queste risorse sono necessarie per il caricamento iniziale della pagina e alcune potrebbero non essere necessarie affatto. Suddividendo il codice in pacchetti, è possibile ottimizzare con il precaricamento selettivo o il caricamento pigro (lazy loading).
I bundler come Webpack modularizzano il codice e utilizzano grafici di dipendenza per determinare quando e dove le risorse sono necessarie. Ciò consente di utilizzare importazioni dinamiche, che rispondono alle chiamate di funzioni all’interno dei moduli. Il bundle splitting è un approccio complementare al code splitting, anche se meno granulare. Coinvolge una separazione guidata dalla configurazione piuttosto che decisioni di caricamento lato client. Un caso d’uso comune è quello di separare le dipendenze di terze parti dal codice della tua applicazione. In questo modo, ciascuno deve essere caricato solo quando ci sono modifiche.
Il code splitting consente anche il tree shaking, un’analisi lato server che rimuove il codice inutilizzato dal tuo bundle di produzione. La maggior parte dei bundler lo fa ora per impostazione predefinita, riducendo le dimensioni del codice senza modificare il comportamento.
Lettura consigliata: La guida definitiva ai concetti fondamentali per i dev di oggi
Lazy Loading
Le strategie di lazy loading separano le risorse critiche da quelle non critiche e servono quest’ultime solo quando necessario. È una tecnica strettamente legata al code splitting.
Chiaramente, una domanda centrale per ogni strategia di lazy loading è la determinazione dei suoi trigger. Può essere semplice come specificare loading=”lazy” nei tag img, che rimanderà il caricamento delle immagini fino a quando non saranno richieste.
È anche possibile configurare il lazy loading di altre risorse monitorando direttamente gli elementi che entrano in vista. L’Intersection Observer API ne è un tipico esempio. Monitora in modo asincrono l’intersezione di un elemento specificato con il viewport, a quel punto è possibile attivare le richieste di risorse.
Utilizzando queste tecniche, il lazy loading può essere applicato alle immagini così come alle risorse multimediali per clip video e animazioni. Anche i moduli Javascript possono essere differiti, così come i CSS. Ciò non solo aiuta ad accelerare le prestazioni della rete, ma impedisce anche al browser di renderizzare gli elementi prima che siano necessari.
Preloading
Mentre il lazy loading rimanda le azioni fino a quando non sono necessarie, il preloading le esegue in anticipo. Alcune risorse non sono immediatamente richieste durante il caricamento della pagina, ma quasi sicuramente saranno necessarie in un secondo momento. In tali casi, può essere utile precaricarle. Ciò si ottiene facilmente utilizzando l’attributo preload. Ad esempio, per precaricare un modulo Javascript:
<code><link rel="preload" as="script" href="myscript.js>
</code>">
Code language: HTML, XML (xml)
Dall’introduzione di HTTP/2, è possibile utilizzare anche il server push per inviare risorse al client prima che vengano richieste direttamente. Ovviamente, è necessario prestare attenzione con queste tecniche per evitare la competizione di larghezza di banda con altre risorse. Il preloading dovrebbe essere utilizzato con parsimonia poiché i browser moderni ottimizzano già l’ordine di caricamento delle risorse.
Ottimizzazione delle immagini
L’ottimizzazione delle immagini è una delle forme più conosciute per ottimizzare le prestazioni web. Tuttavia, può essere facilmente trascurata dai designer che potrebbero essersi abituati alle prestazioni della rete o sapere troppo poco sui formati delle immagini. Prima di tutto, considera se un’immagine è necessaria. CSS3 ora ha effetti sofisticati come ombre e gradienti che in passato i designer utilizzavano con GIF o PNG.
Per le immagini vettoriali più complesse, l’SVG è anche una buona idea. Non solo queste opzioni sono più leggere in termini di byte, ma di solito offrono anche una migliore qualità, adattandosi a qualsiasi risoluzione richiesta.
Per le immagini fotografiche, il livello di compressione è fondamentale. I designer devono bilanciare la qualità dell’immagine rispetto alle dimensioni. È necessario un buon giudizio e un occhio attento, oltre alla consapevolezza delle variazioni nella presentazione su dispositivi e risoluzioni differenti.
Inoltre, assicurati di utilizzare il formato migliore per il tipo di immagini. Il contenuto fotografico è stato tradizionalmente reso come JPEG, ma al giorno d’oggi, WebP e AVIF offrono riproduzioni di migliore qualità con dimensioni di file più piccole. La compatibilità può essere un problema, però: tutti i browser moderni supportano ora WebP, ma AVIF deve ancora essere implementato correttamente su alcuni.
Minimizzazione e Compressione per ottimizzare le prestazioni web
Oltre alla compressione delle immagini, le risorse testuali come CSS e Javascript possono essere ridotte e compresse per migliorare i tassi di trasferimento sulla rete e quindi di riflesso per ottimizzare le prestazioni web. Ciò comporta un’inversione del solito modo di pensare riguardo allo stile del codice: quando si scrive il codice, è importante considerare la leggibilità e la manutenzione.
Ciò significa nomi di variabili significativi, buon uso degli spazi bianchi e utilizzo ponderato dei commenti. Tuttavia, quando si tratta di servire queste risorse, si dovrebbe sacrificare la leggibilità a favore delle dimensioni.
La minimizzazione rimuove gli spazi bianchi in eccesso, i commenti e i delimitatori di blocco ridondanti. Anche la rimozione dei caratteri di nuova riga può avere un impatto misurabile sui tempi di caricamento. La minimizzazione è facilmente realizzabile: troverai una serie di strumenti di minimizzazione da riga di comando che puoi integrare nella tua catena di strumenti, come JSMin e UglifyJS. UglifyJS può anche cambiare cose come i nomi delle variabili per risparmiare ancora più spazio, oltre a offuscare il codice per prevenire il riutilizzo.
Un’altra opzione è la compressione gzip per ridurre le dimensioni delle risorse basate su testo. In genere, questa funzione viene abilitata come parte della configurazione del server web. Ad esempio, con Apache, è possibile utilizzare il modulo mod_deflate.
Caching
Infine, non dimentichiamo la cache. La cache può ottimizzare le prestazioni web riducendo il carico sul server e diminuendo i carichi di trasferimento sulla rete. La cache può essere sia lato server che lato browser. Le cache del tuo browser memorizzano le risorse richieste di recente per evitare di scaricarle di nuovo ogni volta che vengono richieste.
Gli elementi memorizzati nella cache vengono aggiornati dopo la loro scadenza, quando l’intestazione last-modified indica che sono obsoleti o in risposta a un aggiornamento manuale da parte dell’utente. Anche le risorse sensibili o in frequente cambiamento possono essere impostate come “no-cache” per evitare informazioni obsolete.
Un’innovazione più recente è l’utilizzo dei service worker. Si tratta di risorse Javascript che si trovano tra i server web e i browser, agendo come proxy che consente l’accesso offline e migliora le prestazioni delle pagine. Essi includono un’interfaccia Cache programmabile, che è completamente separata dalla cache HTTP utilizzata direttamente dai browser.
Ciò significa che la cache del service worker consente una sintonizzazione più fine-grain per applicazioni specifiche. I tipi di risorse da memorizzare nella cache, così come le loro strategie di aggiornamento, possono essere configurati per offrire un’esperienza veloce e accurata oltre a capacità offline quasi senza soluzione di continuità.
Conclusioni
Ottimizzare le prestazioni web è fondamentale per qualsiasi sito web, app o servizio. Esistono molti approcci, configurabili in base ai risultati desiderati. Questi includono tecniche consolidate e di base come la compressione delle immagini e la cache del browser, oltre a innovazioni più recenti come i service worker Javascript e la gestione delle risorse raggruppate che consente code splitting, lazy loading e ottimizzazioni di preloading. Abbiamo anche visto i vantaggi che una tecnica semplice come la minimizzazione può apportare.
Sebbene abbiamo trattato le basi, l’ottimizzazione non finisce qui. Se sei interessato ad approfondire ulteriormente l’argomento, potresti anche esaminare altre tecnologie lato server come l’ottimizzazione del database e la configurazione dell’infrastruttura, incluso l’utilizzo di CDN per sfruttare tecniche come la distribuzione della cache.