Anche nel 2021, le prestazioni web rimangono un problema. Secondo HTTP Archive, una pagina media richiede un download di 2 MB, fa più di 60 richieste HTTP e può impiegare 18 secondi per caricarsi completamente su un dispositivo mobile. I fogli di stile rappresentano 60 kB divisi in sette richieste, quindi raramente sono una priorità assoluta quando si cerca di affrontare i problemi di prestazioni.

Tuttavia, i CSS hanno un effetto, per quanto lieve possa sembrare. Una volta che avete affrontato il vostro JavaScript, imparare a ottimizzare correttamente il CSS dovrebbe essere la priorità.

Parliamone!

In Che Modo i CSS Influenzano le Prestazioni della Pagina

I CSS sembrano innocenti ma possono richiedere un’elaborazione pesante.

I CSS Bloccano il Rendering

Quando il vostro browser incontra un tag <link> ferma gli altri download e l’elaborazione del browser mentre recupera e analizza il file CSS.

Anche JavaScript può bloccare il rendering del browser, ma l’elaborazione asincrona è possibile grazie a:

  1. L’attributo async per scaricare gli script in parallelo, che vengono eseguiti immediatamente quando sono pronti.
  2. L’attributo defer per scaricare in parallelo, quindi eseguire secondo l’ordine quando il DOM è pronto.
  3. L’attributo type="module" per caricare un modulo ES (che si comporta come il defer).

Le risorse come le immagini spesso richiedono più larghezza di banda, ma sono disponibili formati efficienti e possono essere caricate in lazy-loading (attributo loading="lazy" ) senza bloccare il rendering del browser.

Niente di tutto questo è possibile con i CSS. Il file viene memorizzato nella cache, quindi i successivi caricamenti della pagina dovrebbero essere più veloci, ma il processo di blocco del rendering rimane.

I File CSS di Grandi Dimensioni Richiedono Tempo per Essere Processati

Più grande è il vostro foglio di stile, più tempo ci vuole per scaricarlo ed elaborarlo in un CSSOM (CSS Object Model), che il browser e le API JavaScript possono usare per visualizzare la pagina. Anche se i fogli di stile CSS sono più piccoli della maggior parte degli altri file web, non sono immuni dalla regola empirica “più piccolo è, meglio è”.

I File CSS Crescono

Può essere difficile identificare gli stili che non sono più utilizzati e rimuovere quelli sbagliati può generare il caos in un sito. Chi lavora nello sviluppo, di solito opta per l’approccio più sicuro “conserva tutto”. Gli stili di pagina, i componenti e i widget che non sono più utilizzati continuano a esistere nei CSS. Il risultato? La dimensione del file, la complessità e lo sforzo di manutenzione aumentano esponenzialmente, e questo significa meno propensione da parte dei professionisti dello sviluppo a rimuovere il codice ridondante.

I Fogli di Stile Possono Fare Riferimento ad Altre Risorse

I CSS possono fare riferimento ad altri fogli di stile grazie alle regole @import. Queste importazioni bloccano l’elaborazione del foglio di stile corrente e caricano altri file CSS in serie.

Anche altre risorse, come font e immagini, possono essere referenziate. Il browser cercherà di ottimizzare i download, ma in caso di dubbio, li recupererà immediatamente. I file codificati in base64 subiscono ancora un’ulteriore elaborazione.

Rendering degli Effetti CSS

I browser hanno tre fasi di rendering:

  1. La fase di layout (o reflow) calcola le dimensioni di ogni elemento e come esso influisce sulla dimensione o sul posizionamento degli elementi intorno ad esso.
  2. La fase di paint disegna le parti visive di ogni elemento su livelli separati: testo, colori, immagini, bordi, ombre, ecc.
  3. Il composite disegna ogni strato sulla pagina nell’ordine corretto secondo i contesti di impilamento, posizionamento, z-index, ecc.

Se non prestate attenzione, i cambiamenti di proprietà CSS e le animazioni possono causare un nuovo rendering di tutte e tre le fasi. Alcune proprietà, come le ombre e i gradienti, sono anche computazionalmente più costose dei colori del blocco e dei margini.

Strumenti di Analisi delle Prestazioni CSS

Ammettere di avere un problema di prestazioni CSS è il primo passo sulla strada verso il recupero! Trovare e risolvere le cause è un’altra questione.

I seguenti strumenti e servizi (non classificati in un ordine specifico) possono aiutarvi a identificare i colli di bottiglia degli stili nel vostro codice.

1. Pannello Network in DevTools

Gli specialisti delle prestazioni web passano molto tempo su DevTools e nel pannello Network (o Rete) in particolare. DevTools è nativo per la maggior parte dei browser moderni, ma noi useremo Google Chrome per gli esempi.

DevTools può essere aperto dal menu del browser, di solito da Altri strumenti > Strumenti di sviluppo, o tramite le scorciatoie da tastiera Ctrl | Cmd + Shift + I o F12.

Andate alla scheda Rete e verificate che l’opzione Disabilita la cache sia selezionata per evitare che i file nella cache influenzino il rapporto. Potete anche cambiare l’opzione throttling per simulare le reti mobili più lente.

Aggiornate la pagina per visualizzare il grafico a cascata del download e dell’elaborazione:

Pannello di rete di DevTools
Pannello di rete di DevTools

Qualsiasi barra lunga nel grafico è motivo di preoccupazione, ma dovreste focalizzarvi in particolare sulle barre lunghe bloccate o in stallo (mostrate in bianco). In questo esempio, la riga evidenziata e tutte le righe seguenti non potevano iniziare il download fino a quando i file CSS e JavaScript che bloccano il rendering non fossero stati elaborati all’inizio della pagina HTML.

La casella Filtro vi permette di mostrare o nascondere risorse specifiche:

  • larger-than:<S>: limita ai file più grandi di <S>, espresso in byte (10.000), Kilobyte (1.000 kB), o megabyte (1 M).
  • -larger-than:<S>: limita ai file più piccoli di <S>.
  • -domain:*<.yourdomain.com>: mostra le richieste di terzi che non sono caricate dal vostro dominio primario. Queste sono una delle principali cause della lentezza dei siti.

Una pagina ad alte prestazioni con CSS ottimizzato ha tipicamente meno risorse caricate in parallelo con barre bloccate o in stallo più brevi.

2. WebPageTest

WebPageTest fornisce una simile visualizzazione a cascata della rete, così come molti altri grafici sulle prestazioni:

WebPageTest.org asset waterfall
WebPageTest.org asset waterfall

Il servizio usa dispositivi basati in varie località globali in modo da poter valutare le prestazioni del mondo reale e le ottimizzazioni CSS.

3. Pannello DevTools Lighthouse di Chrome

Il pannello DevTools Lighthouse è incluso nei browser basati su Chromium come Chrome, Edge, Brave, Opera e Vivaldi. Potete generare rapporti sulle prestazioni, Progressive Web App, Best Practices, Accessibilità e Ottimizzazione dei motori di ricerca per dispositivi mobile e desktop.

Pannello DevTools Lighthouse
Pannello DevTools Lighthouse

Lo strumento fornisce suggerimenti di miglioramento, compresi i modi per ottimizzare i CSS. Non tutti possono essere pratici o possibili, ma vengono evidenziati i vantaggi principali.

4. Google PageSpeed Insights

PageSpeed Insights è la versione online di Lighthouse. Ha meno funzioni ma può essere usato in qualsiasi browser e fornisce alcuni approfondimenti alternativi.

Per esempio, questa alberatura mostra le più grandi risorse JavaScript con una metrica di copertura, che indica quale proporzione di codice è usata e quale no:

Alberatura di Google PageSpeed Insights
Alberatura di Google PageSpeed Insights

Il CSS non viene visualizzato, ma la quantità di JavaScript avrà un peso sull’efficienza degli stili.

Strumenti simili per testare la velocità del sito web includono Pingdom Website Speed Test e GTmetrix.

5. Pannello Coverage di Chrome DevTools

Il pannello di Coverage DevTools nei browser basati su Chromium aiuta a localizzare il codice CSS (e JavaScript) inutilizzato. Selezionate Coverage dal sottomenu DevTools More tools, poi aggiornate la pagina e navigate sul sito/applicazione:

Pannello Coverage di DevTools
Pannello Coverage di DevTools

Le risorse CSS e JavaScript sono mostrate nel pannello Coverage, con la proporzione di codice inutilizzato in rosso. Fate clic su qualsiasi file per visualizzare il codice sorgente con il codice inutilizzato evidenziato in rosso nel gutter del numero di linea.

Alcune cose di cui prendere nota:

  • Le metriche di copertura si resettano se aggiornate o passate a una nuova pagina, come succede su un sito WordPress. La metrica del codice inutilizzato diminuisce solo se state navigando in una Single Page Application che carica il contenuto senza un aggiornamento della pagina.
  • Lo strumento può solo tenere conto del CSS utilizzato fino a un determinato momento. Non può determinare se un widget non è stato visualizzato o ha più stati legati a JavaScript.

6. Monitoraggio delle Prestazioni in Tempo Reale su Chrome DevTools

I browser basati su Chromium includono un Monitor delle prestazioni in tempo reale. Anche questo è disponibile dal menu DevTools More tools. I grafici si aggiornano mentre navigate nelle pagine, le scorrete e attivate le animazioni:

Monitoraggio delle Prestazioni in Tempo Reale su DevTools.
Monitoraggio delle Prestazioni in Tempo Reale su DevTools.

Le seguenti metriche sono di particolare interesse per ottimizzare le prestazioni dei CSS (più basse sono, meglio è):

  • Utilizzo della CPU: Utilizzo del processore da 0% a 100%.
  • Layout/sec: La velocità con cui il browser deve ridisegnare la pagina.
  • Ricalibrazione stile/sec: La velocità con cui il browser deve ricalcolare gli stili.

Anche le altre metriche possono essere utili se il CSS sta avendo difficoltà a causa di fattori esterni (di nuovo, valori più bassi indicano migliori prestazioni):

  • Dimensione heap JS: La memoria totale utilizzata dagli oggetti JavaScript.
  • Nodi DOM: Il numero di elementi nel documento HTML.
  • Listener di eventi JS: Il numero di listener di eventi JavaScript registrati.
  • Documenti: Il numero di risorse, incluse la pagina, i file CSS, i moduli JavaScript, ecc.
  • Frame del documento: Il numero di frame, iframe e script JavaScript worker.

7. Rapporto sulle Prestazioni di DevTools

Il pannello delle prestazioni di DevTools vi permette di registrare le attività della pagina per ulteriori analisi e aiutare a identificare i problemi di prestazioni. I rapporti generati sono complessi e chi lavora nello sviluppo spesso li evita, ma forniscono informazioni preziose.

L’icona delle impostazioni del pannello Prestazioni vi permette di impostare varie opzioni, come il rallentamento della rete e della CPU. Potete anche disabilitare i campioni JavaScript in modo che gli stack delle chiamate dettagliate non vengano registrati.

Per iniziare, fate clic sull’icona circolare Record, caricate e/o usate la vostra pagina, poi fate clic sul pulsante Stop per visualizzare il rapporto:

Rapporto sulle prestazioni di DevTools
Rapporto sulle prestazioni di DevTools

Quasi tutte queste metriche saranno utili a chi sviluppa JavaScript, ma i problemi di ottimizzazione CSS possono essere particolarmente evidenti grazie a:

  • Barra rossa in alto: Questo indica che il frame rate è sceso significativamente, il che potrebbe causare problemi di prestazioni. È previsto all’inizio del caricamento di una pagina, ma anche le eccessive animazioni CSS potrebbero essere un problema.
  • Grafico riassuntivo: Metriche elevate di caricamento, rendering e painting possono indicare problemi di CSS.

Correzioni Indirette delle Prestazioni CSS

Le seguenti correzioni non risolvono direttamente i problemi CSS, ma possono aiutarvi a risolvere alcuni problemi di prestazioni con uno sforzo relativamente piccolo.

Usare un Buon Host

Usare un buon host con server fisicamente più vicini ai vostri utenti porterà benefici immediati in termini di prestazioni. I piani di hosting variano, ma esistono tre tipi principali:

  1. Hosting condiviso: Il vostro sito web è ospitato su un server fisico, probabilmente insieme a centinaia di altri siti. Spazio su disco, RAM, tempo di CPU e larghezza di banda sono condivisi. I piani sono spesso economici, ma le prestazioni e la disponibilità sono influenzate dagli altri siti. L’aggiornamento può essere possibile, ma il vostro sito rimarrà generalmente sulla stessa infrastruttura.
  2. Hosting dedicato: Il vostro sito è ospitato su uno o più server fisici di vostra proprietà. L’hardware può essere configurato e aggiornato secondo le esigenze. I piani sono spesso costosi e i guasti all’hardware rimangono problematici.
  3. Cloud hosting: Il cloud hosting astrae l’infrastruttura hardware in un insieme di servizi a cui si può accedere su richiesta. Il vostro sito potrebbe essere fornito su una serie di dispositivi per facilitare gli aggiornamenti.

I piani di cloud hosting e i prezzi variano enormemente. Potreste prendere in considerazione:

  1. Opzioni Platform as a Service (PaaS), come server web virtuali e database, o
  2. Opzioni Software as a Service (SaaS), che offrono applicazioni completamente gestite come WordPress.

Cambiare host può aumentare le prestazioni. È improbabile che risolva tutti i vostri problemi, ma è una soluzione economica ai problemi di backend e di larghezza di banda. Potreste anche considerare l’utilizzo di un Content Delivery Network (CDN) o di un CDN specializzato in immagini e video che può distribuire il carico su più posizioni geograficamente più vicine agli utenti.

Sfruttare le Caratteristiche di Efficienza del Browser e del Server

Circa il 10% dei siti non attiva la compressione gzip (o migliore), che di solito è l’opzione predefinita del server. Questo riduce la dimensione dei CSS del 60% o più comprimendo i file prima della trasmissione. Non sistemerà i CSS inefficienti, ma il codice arriverà prima!

Dovreste anche attivare HTTP/2 (o meglio), che invia dati in un formato binario più piccolo, comprime le intestazioni e può inviare più di un file sulla stessa connessione TCP.

Infine, assicuratevi che il browser possa mettere in cache i CSS e altri file in modo efficace. Di solito si tratta di impostare gli hashtag Expires, Last-Modified e/o ETag nell’intestazione HTTP.

Ottimizzare il CMS

I sistemi di gestione dei contenuti come WordPress possono essere estesi con temi e plugin che servono i propri CSS. Dove possibile, dovreste velocizzare il vostro CMS per:

  1. Rimuovere i plugin inutilizzati.
  2. Usare temi più snelli
  3. Abilitare il caching per evitare un’eccessiva rigenerazione delle pagine.

Ottimizzare le Immagini

Le immagini non hanno lo stesso overhead di elaborazione e rendering di HTML, CSS e JavaScript, ma rappresentano una grande proporzione del peso della pagina e della larghezza di banda utilizzabile. Considerate di:

  1. Rimuovere le immagini non necessarie.
  2. Ridimensionare le immagini grandi, forse non più del 150% della dimensione massima che possono apparire sullo schermo.
  3. Usare un formato immagine appropriato, idealmente un’opzione altamente compressa come WebP o AVIF, ma possibilmente SVG per loghi e grafici.
  4. Sostituire le immagini con gradienti CSS o altri effetti.
  5. Aggiungere attributi di larghezza e altezza ai tag HTML <img> o usando la nuova proprietà CSS aspect-ratio per assicurare che lo spazio appropriato sia riservato sulla pagina prima che l’immagine venga scaricata.

Un CDN specializzato in immagini può gestire parte di questo lavoro per voi. Per altri consigli, date un’occhiata alla nostra guida su come ottimizzare le immagini per il web.

Rimuovere il CSS Inutilizzato

Gli stili più veloci sono quelli che non avete mai bisogno di caricare o visualizzare! Provate a rimuovere/modificare qualsiasi codice CSS di cui non avete più bisogno, come quello per le pagine legacy, i widget o i framework. Questo può essere difficile su siti più grandi e non è sempre chiaro se un particolare insieme di stili sia essenziale o meno.

I seguenti strumenti analizzano l’uso dell’HTML e dei CSS al momento della costruzione o scansionando gli URL per identificare il codice ridondante. Questo non è sempre adeguato, quindi potete impostare ulteriori configurazioni per assicurare che gli stili attivati da JavaScript e dalle interazioni dell’utente siano elencati:

C’è un’opzione migliore: dividere i CSS in file separati con chiari livelli di responsabilità e documentati di conseguenza. Rimuovere gli stili non necessari diventa quindi molto più facile.

Ottimizzare le Prestazioni di Caricamento dei CSS

Non tutti i CSS vengono caricati allo stesso modo. L’umile tag <link> contiene una serie di opzioni e stranezze che non sono sempre logiche.

Ottimizzare l’Uso dei Font Web

Google Fonts e librerie di font simili hanno rivoluzionato i font web, ma poche righe di codice di font possono incorrere in centinaia di kilobyte di larghezza di banda.

Ecco i nostri suggerimenti per l’ottimizzazione:

  1. Caricare solo i font di cui avete bisogno: rimuovete font che non state usando e verificate che non siano necessari nuovi font.
  2. Caricare solo i pesi e gli stili di cui avete bisogno: la maggior parte delle librerie di font può limitare il download a certi set di caratteri (come solo il latino), pesi (spessori) e corsivi (inclinazioni). I browser possono visualizzare automaticamente gli stili mancanti, anche se i risultati possono essere scarsi.
  3. Limitare i caratteri richiesti: i font usati di rado possono essere limitati a caratteri specifici. Per esempio, il titolo “tutorial CSS” in Open Sans può essere definito aggiungendo un parametro &text= alla stringa di ricerca dei font di Google: fonts.googleapis.com/css?family=Open+Sans&text=CStuorial
  4. Considerare i font variabili: i font variabili definiscono una grande varietà di stili, pesi e corsivi usando l’interpolazione vettoriale. Il file del font è un po’ più grande, ma ne serve solo uno piuttosto che diversi. Il font ricorsivo dimostra la flessibilità dei font variabili.
  5. Caricare i font dal vostro server locale: ospitare in locale i font è più efficiente dell’utilizzo di una libreria di font. Servono meno ricerche DNS e potete limitare il download a WOFF2, che tutti i browser moderni supportano. I browser più vecchi (stiamo guardando te, Internet Exploere) possono ripiegare su un font OS.
  6. Considerare i font OS: quel font web da 500 kB può sembrare fantastico, ma qualcuno se ne accorgerebbe se voi passaste ai popolari Helvetica, Arial, Georgia o Verdana? I font web-safe o OS sono un modo semplice per aumentare le prestazioni.

Usare un’Opzione di Caricamento dei Font Appropriata

I font web possono richiedere alcuni secondi per essere scaricati ed elaborati. Il browser si comporta in uno dei due modi:

  1. Mostrare un Flash of Unstyled Text (FOUT): il primo font di ripiego disponibile viene usato inizialmente ma viene sostituito una volta che il font web è pronto.
  2. Mostrare un Flash of Invisible Text (FOIT): nessun testo viene visualizzato fino a quando il web font non è pronto. Questo è il processo predefinito nei browser moderni, che tipicamente aspettano tre secondi prima di tornare a un font di ripiego.

Nessuno dei due comportamenti è ideale. La proprietà CSS font-display e il parametro Google Font & display = possono selezionare un’opzione alternativa:

  • auto: il comportamento predefinito del browser (di solito FOIT).
  • block: FOIT. Il testo è invisibile fino a tre secondi. Non c’è un cambio di font, ma il testo può impiegare del tempo per apparire.
  • swap: FOUT. Il primo fallback viene utilizzato fino a quando il font web non è disponibile. Il testo è immediatamente leggibile, ma l’effetto del cambio di font può essere stridente. Font Style Matcher può essere usato per definire un fallback di dimensioni simili.
  • fallback: un compromesso tra FOIT e FOUT. Il testo è invisibile per un breve periodo (tipicamente 100 ms), poi viene usato il primo fallback fino a quando il font web è disponibile.
  • optional: simile a fallback, eccetto che non si verifica alcuno scambio di font. Il web font viene utilizzato solo se è disponibile entro il periodo iniziale. La visualizzazione della vostra prima pagina mostrerà probabilmente un font di fallback, mentre le visualizzazioni successive useranno il font web scaricato e memorizzato nella cache.

L’utilizzo di swap, fallback, o optional può offrire un aumento delle prestazioni percepite.

Evitare CSS @import

L’at-rule @import permette ai file CSS di essere inclusi in altri:

/* main.css */
@import url("reset.css");
@import url("grid.css");
@import url("widget.css");

Questo sembra un modo efficace per caricare componenti e font più piccoli. Sfortunatamente, ogni @import blocca il rendering e ogni file deve essere caricato e analizzato in serie.

Molteplici tag <link> all’interno dell’HTML sono più efficienti e caricano i file CSS in parallelo:

<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="grid.css">
<link rel="stylesheet" href="widget.css">

Detto questo, è meglio…

Concatenare e Minimizzare i CSS

I moderni strumenti di compilazione, i preprocessori CSS come Sass e i plugin di WordPress possono combinare tutti i partial in un unico grande file CSS. Gli spazi bianchi non necessari, i commenti e i caratteri vengono poi rimossi per ridurre la dimensione del file al minimo.

I file multipli diventano meno problematici in termini di prestazioni con HTTP/2 e versioni superiori, ma un singolo file richiede solo un’intestazione e può essere gzippato e messo in cache in modo più efficiente.

I file CSS separati sono pratici solo quando avete uno o più fogli di stile che vengono cambiati frequentemente, forse diverse volte a settimana. Anche allora, il codice CSS più statico può essere combinato in un unico file.

I clienti di Kinsta possono accedere alla funzione di minificazione del codice nel loro cruscotto MyKinsta. La funzione consente ai clienti di attivare la minificazione automatica di CSS e JavaScript con un semplice clic. Ciò contribuisce a velocizzare un sito senza alcuno sforzo manuale.

Evitare la Codifica Base64

Gli strumenti possono codificare le immagini in stringhe base64, che potete usare come URI di dati nei tag HTML <img> e negli sfondi CSS:

.background {
  background-image: url('data:image/jpg;base64,ABC123...');
}

Questo riduce il numero di richieste HTTP, ma danneggia le prestazioni dei CSS:

  • Le stringhe base64 possono essere il 30% più grandi del loro equivalente binario.
  • I browser devono decodificare la stringa prima che un’immagine possa essere utilizzata.
  • Alterare un pixel dell’immagine invalida l’intero file CSS.

Considerate la codifica base64 solo se state usando immagini molto piccole, che cambiano raramente, dove la stringa risultante non è significativamente più lunga di un URL.

Detto questo, potete codificare in UTF8 le icone SVG riutilizzabili, per esempio:

.svgbackground {
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><circle cx="300" cy="300" r="150" stroke-width="3" stroke="#f00" fill="#ff0" /></svg>');
}

Rimuovere gli Hack CSS e i Fallback di IE

A meno che non siate sfortunati e abbiate un’alta percentuale di utenti Internet Explorer, i fogli di stile condizionali e gli hack di IE possono essere rimossi dal vostro CSS. Nella maggior parte dei casi, gli utenti IE vedranno ancora qualcosa, specialmente se usate un design mobile-first che mostra una vista lineare più semplice per impostazione predefinita. Il risultato potrebbe non essere bello e non sarà perfetto, ma spenderete meglio il vostro budget di sviluppo considerando l’accessibilità per tutti gli utenti.

Precaricare i File CSS

Il tag <link> fornisce un attributo opzionale di precaricamento che può iniziare un download immediatamente piuttosto che aspettare il vero riferimento nell’HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My page</title>
  <!-- preload styles -->
  <link rel="preload" href="/css/main.css" as="style" />
  <!-- lots more code -->
  <!-- load preloaded styles -->
  <link rel="stylesheet" href="/css/main.css" />

Questo è particolarmente vantaggioso in WordPress e in altri CMS dove un plugin potrebbe aggiungere un foglio di stile più in basso nella pagina.

Utilizzare il CSS Critico Inline

Gli strumenti di analisi possono suggerirvi di “inserire inline i CSS critici” o “ridurre i fogli di stile che bloccano il rendering”. Questo migliora le prestazioni perché:

  1. Identifica gli stili essenziali usati dagli elementi above the fold (quelli visibili quando la pagina viene caricata).
  2. Inserisce il CSS critico in un tag <style> nel vostro <head>
  3. Carica il CSS rimanente in modo asincrono per evitare il blocco del rendering. Questo si può realizzare caricando il foglio di stile in uno stile “print” a cui il browser dà una priorità inferiore. JavaScript poi lo commuta in uno stile media “all” una volta che la pagina è stata caricata (un <noscript> assicura che il CSS funzioni se JavaScript non è disponibile):
<style>
/* critical styles */
body { font-family: sans-serif; color: #111; }
</style>
<!-- load remaining styles -->
<link rel="stylesheet"
     href="/css/main.css"
    media="print"
   onload="this.media='all'">
<noscript>
  <link rel="stylesheet" href="/css/main.css">
</noscript>

Strumenti come critical e criticalCSS possono aiutare a estrarre gli stili per gli elementi in-view.

La tecnica migliora notevolmente le prestazioni e aumenta i punteggi di controllo. Siti o applicazioni con interfacce coerenti dovrebbero essere più semplici da implementare, ma potrebbe essere più difficile altrove:

  • Uno strumento di costruzione è essenziale per tutti i siti tranne i più semplici.
  • Il significato di “fold” cambia a seconda del dispositivo.
  • I siti potrebbero avere una varietà di layout che richiedono diversi CSS critici.
  • Gli strumenti CSS critici possono lottare con framework specifici, HTML generato lato client e contenuti dinamici.
  • La tecnica beneficia principalmente il caricamento della prima pagina. I CSS vengono memorizzati nella cache per le pagine successive, quindi gli stili aggiuntivi delineati aumenteranno il peso della pagina.

Usare il Rendering Media Query

Un singolo file concatenato e minificato andrà a beneficio della maggior parte dei siti, ma i siti che richiedono una quantità significativa di stili a schermo più grande potrebbero dividere i file CSS e caricarli usando una media query:

<!-- core styles loaded on all devices -->
<link rel="stylesheet" href="core.css">
<!-- served to screens at least 40em wide -->
<link rel="stylesheet" media="(min-width: 40em)" href="40em.css">
<!-- served to screens at least 80em wide -->
<link rel="stylesheet" media="(min-width: 80em)" href="80em.css">

Questo esempio presuppone una metodologia mobile-first. I dispositivi mobili caricano core.css ma potrebbero non aver bisogno di scaricare o analizzare i fogli di stile rimanenti.

Usare il Rendering Progressivo

Il rendering progressivo è una tecnica che definisce fogli di stile individuali per pagine o componenti separati. Può avvantaggiare siti molto grandi dove le singole pagine sono costruite da una vasta gamma di componenti.

Ogni file CSS viene caricato immediatamente prima che un componente sia referenziato nell’HTML:

<head>
  <!-- core styles -->
  <link rel="stylesheet" href="core.css" />
</head>
<body>
  <!-- header -->
  <link rel="stylesheet" href="header.css" />
  <header>...</header>
  <!-- primary content -->
  <link rel="stylesheet" href="main.css" />
  <main>
    <!-- widget styling -->
    <link rel="stylesheet" href="widget.css" />
    <div class="mywidget>...</div>
  </main>
  <!-- footer -->
  <link rel="stylesheet" href="footer.css" />
  <footer>...</footer>
</body>

Questo funziona bene nella maggior parte dei browser. (Safari mostra una pagina bianca fino a quando tutto il CSS non viene caricato, ma non dovrebbe essere molto peggio di un singolo foglio di stile grande.)

L’adozione dei componenti web incoraggia anche l’uso di stili con attributo “scoped” che vengono caricati durante la visualizzazione dell’elemento personalizzato.

Ottimizzare le Prestazioni CSS

Le tecniche e le proprietà CSS mettono a dura prova il browser, la CPU, la memoria, la larghezza di banda e altre risorse. I seguenti suggerimenti possono aiutarvi a evitare elaborazioni inutili e prestazioni lente.

Adottare le Tecniche di Layout Moderne (Grid e Flexbox)

I layout basati su float sono difficili da creare, usano numerose proprietà, richiedono continui aggiustamenti dei margini e del padding, devono essere gestiti tramite le media query e richiedono una notevole elaborazione da parte del browser. Sono stati l’unico metodo di layout valido per molti anni, ma non sono più necessari. Usate uno dei due:

  • CSS Flexbox per layout monodimensionali che potrebbero avvolgere la riga successiva. È ideale per menu, gallerie di immagini, schede, ecc.
  • CSS Grid per layout bidimensionali con righe e colonne esplicite. È ideale per i layout di pagina.

Entrambi sono più semplici da sviluppare, usano meno codice, vengono visualizzati più velocemente e si adattano a qualsiasi dimensione dello schermo senza media queries.

I browser molto vecchi non riconosceranno le moderne proprietà flexbox e grid, quindi ogni elemento diventa un blocco. Mostrateli in un semplice layout lineare da mobile: non c’è bisogno di emulare il design con fallback basati su float.

Sostituite le Immagini con Gradienti ed Effetti CSS

Dove possibile, optate per il codice CSS piuttosto che per le immagini. Sperimentate con gradienti, bordi, raggi, ombre, filtri, modalità di fusione, maschere, ritaglio ed effetti pseudo-elemento per riutilizzare o sostituire le immagini esistenti.

Gli effetti CSS usano molto meno banda, sono più facili da modificare e di solito possono essere animati.

Evitare l’Uso Eccessivo di Proprietà Costose

Anche se potreste già avere un codice dichiarativo conciso, alcuni CSS richiedono più elaborazione di altri. Le seguenti proprietà innescano calcoli di painting che possono essere costosi se usati in eccesso:

  • position: fixed
  • border-radius
  • box-shadow
  • text-shadow
  • opacity
  • transform
  • filter
  • backdrop-filter
  • background-blend-mode

Usare Transizioni e Animazioni CSS Quando Possibile

Le transizioni e le animazioni CSS saranno sempre più fluide degli effetti alimentati da JavaScript, che modificano proprietà simili. Non saranno processati nei browser molto vecchi ma, dato che è probabile che questi girino su dispositivi meno capaci, è meglio così.

Tuttavia, evitate le eccessive animazioni. Gli effetti dovrebbero migliorare l’esperienza dell’utente senza influenzare negativamente le prestazioni o farvi venire il mal di mare. Verificate la media query prefers-reduced-motion e disabilitate le animazioni quando necessario.

Evitare di Animare le Proprietà che Innescano un Ri-Layout

Alterare le dimensioni di un elemento (larghezza, altezza, padding, bordo) o la posizione (superiore, inferiore, sinistra, destra, margine) può richiedere il ri-layout dell’intera pagina a ogni fotogramma di animazione. Le proprietà più efficienti da animare sono:

  • opacity.
  • filter: sfocatura, contrasto, ombra e altri effetti.
  • transform: per tradurre (spostare), scalare o ruotare un elemento.

I browser possono usare la GPU con accelerazione hardware per renderizzare questi effetti nel proprio livello, quindi solo la fase di composizione è interessata.

Se dovete animare altre proprietà, potete migliorare le prestazioni togliendo l’elemento dal flusso della pagina con position: absolute.

Attenzione ai Selettori Complessi

I browser analizzano rapidamente i selettori CSS più complessi, ma semplificarli riduce le dimensioni dei file e migliora le prestazioni. I selettori complessi sono spesso generati quando si creano strutture profondamente annidate nei preprocessori CSS come Sass.

Indicare Quali Elementi Cambieranno

La proprietà CSS will-change vi permette di avvertire come un elemento verrà cambiato o animato in modo che il browser possa fare delle ottimizzazioni in anticipo:

.myelement {
  will-change: transform, opacity;
}

Qualsiasi numero di valori separati da virgola può essere definito, ma la proprietà dovrebbe essere usata solo come ultima risorsa per risolvere problemi di prestazioni noti. Non dovreste applicarla a troppi elementi e assicurarvi di darle tempo sufficiente per inizializzarsi.

Considerare il Containment CSS

Il containment è una nuova caratteristica CSS che può migliorare le prestazioni permettendovi di identificare i sottoinsiemi isolati di una pagina. Il browser può ottimizzare l’elaborazione rendendo, o non rendendo, uno specifico blocco di contenuto DOM.

La proprietà contain accetta uno o più dei seguenti valori in una lista separata da spazi:

  • none: il containment non viene applicato.
  • layout: il layout dell’elemento è isolato dal resto della pagina, il suo contenuto non influenzerà altri elementi.
  • paint: i figli dell’elemento non sono visualizzati al di fuori del suo confine.
  • size: la dimensione dell’elemento può essere determinata senza controllare gli elementi figli, le dimensioni sono indipendenti dal contenuto.

Sono disponibili anche due valori speciali:

  • strict: applica tutte le regole di containment (eccetto “none”).
  • content: applica il layout e il colore.

Il Containment CSS è supportato nella maggior parte dei browser moderni. Non viene supportato in Safari o nelle applicazioni più vecchie, ma il containment può comunque essere usato anche in quel caso perché il browser ignorerà semplicemente la proprietà.

Reagire all’Intestazione Save-Data

Save-Data è un’intestazione di richiesta HTTP che indica che l’utente ha richiesto dati ridotti. Può essere etichettato come modalità “Lite” o “Turbo” in alcuni browser.

Quando è abilitata, un’intestazione Save-Data viene inviata con ogni richiesta del browser:

GET /main.css HTTP/1.0
Host: site.com
Save-Data: on

Il server può rispondere di conseguenza quando viene rilevato Save-Data. Nel caso dei CSS, potrebbe inviare un layout lineare più semplice simile a quello dei cellulari, usare un font OS, passare a colori a blocchi o caricare sfondi di immagini a bassa risoluzione.

Tenete presente che il server dovrebbe restituire la seguente intestazione sulle richieste modificate per assicurare che il contenuto minimo non sia memorizzato nella cache e riutilizzato quando l’utente spegne la modalità Lite/Turbo:

Vary: Accept-Encoding, Save-Data

L’intestazione può anche essere rilevata da JavaScript lato client. Il seguente codice aggiunge una classe bestUX all’elemento <html> quando Save-Data non è abilitato:

if ('connection' in navigator && !navigator.connection.saveData) {
  document.documentElement.classList.add('bestUX');
}

I fogli di stile possono quindi reagire di conseguenza senza alcuna manipolazione del server:

/* no hero image by default */
header {
  background-color: #abc;
  background-image: none;
}
/* hero image when no Save-Data */
.bestUX header {
  background-image: url("hero.jpg");
}

La media query prefers-reduced-data offre un’opzione CSS-only come alternativa, anche se questa non è supportata in nessun browser nel momento in cui scriviamo questo articolo:

/* no hero image by default */
header {
  background-color: #abc;
  background-image: none;
}
/* hero image when no Save-Data */
@media (prefers-reduced-data: no-preference) {
  header {
    background-image: url("hero.jpg");
  }
}

Riepilogo

Ci sono molte opzioni per ottimizzare le prestazioni dei CSS, ma per i nuovi progetti, considerate le seguenti pratiche:

  1. Usare un approccio mobile-first: codificate prima il layout mobile più semplice, poi aggiungete miglioramenti man mano che lo spazio dello schermo e le funzionalità del browser aumentano.
  2. Dividere i CSS in file separati con responsabilità identificabili: un preprocessore CSS o un plugin CMS può combinare i parziali CSS in un unico file.
  3. Aggiungere un passo di compilazione: sono disponibili degli strumenti che possono automaticamente limare il codice, identificare i problemi, concatenare, minimizzare, ridurre le dimensioni delle immagini e altro. L’automazione rende la vita più facile, ed è meno probabile dimenticare un passaggio di ottimizzazione.
  4. Documentare i vostri fogli di stile: una guida di stile con esempi documentati renderà il vostro codice più facile da scegliere e mantenere. Sarete in grado di identificare e rimuovere il vecchio CSS senza sudare troppo.

Infine, imparate il CSS! Più ne sapete, meno codice dovrete scrivere e più veloce diventerà la vostra applicazione web. Migliorerete molto il vostro lavoro indipendentemente dalle piattaforme e dai framework che usate.

Quali altri consigli avete per ottimizzare le prestazioni dei CSS? Condivideteli nella sezione dei commenti!

Craig Buckler

Freelance UK web developer, writer, and speaker. Has been around a long time and rants about standards and performance.