Minificatore CSS

Comprimi codice CSS rimuovendo commenti, spazi e ottimizzando i valori.

Informazioni sulla minificazione CSS

È tentante assumere che, poiché Brotli comprime gli stream di testo così aggressivamente, il valore marginale di un passaggio di minificazione separato sia collassato. Il blog ingegneristico di Sentry ha sostenuto esattamente quell'argomento nell'aprile 2024 e ha concluso il contrario: la minificazione paga ancora. Con la velocità mediana globale di internet mobile attorno ai 53 Mbps e Brotli universalmente distribuito al margine della CDN, "se puoi tagliare via solo 1 KB da un totale di 100 risorse a ogni caricamento di pagina, potresti star facendo un miglioramento di 15 ms sulla velocità della pagina per quegli utenti." Moltiplicato sulla base di visitatori di qualsiasi sito non banale, ciò diventa una vera fattura della larghezza di banda, un vero costo in batteria sui dispositivi mobile e un vero cambio di posizione su un report Lighthouse.

Il meccanismo conta. Gzip e Brotli sono compressori lossless general-purpose che cercano sequenze di byte ripetute e codificano ogni ripetizione come un riferimento all'indietro in un dizionario a finestra scorrevole. Due file CSS che producono lo stesso comportamento del browser ma contengono byte diversi si comprimeranno a due dimensioni diverse. margin: 10px 10px 10px 10px; e margin:10px sono semanticamente identici, ma il primo ha più caratteri da codificare anche se molti sono ripetizioni: Brotli è bravo a trovare ripetizione ma non capisce che due stringhe CSS sintatticamente distinte esprimono la stessa regola. Solo un minificatore consapevole di CSS può farlo. L'hub di apprendimento di Cloudflare colloca le riduzioni tipiche di testo grezzo al 30-50%; Brotli sopra aggiunge un altro modesto 5-15%, ma non è zero, e su larga scala fa la differenza.

Il CSS è render-blocking, ed è per questo che i byte contano

Largest Contentful Paint è uno dei tre Core Web Vitals; la soglia per "Buono" è 2,5 secondi al 75° percentile dei caricamenti di pagina. Il punteggio Performance complessivo di Lighthouse pesa LCP al 25% del totale. Il CSS è render-blocking di default: quando il browser vede un <link rel="stylesheet"> mette in pausa il rendering finché quel file non è scaricato e il CSSOM è costruito, perché regole più tarde nel foglio di stile possono sovrascriverne di precedenti e il browser non può rischiare di disegnare in uno stato non stilizzato o stilizzato male. Il CSS Object Model, a differenza del DOM, non è costruito incrementalmente: il parser ha bisogno dell'intero foglio di stile per sapere quali regole vincono. Anche JavaScript blocca su questo: gli script non possono girare in modo sicuro mentre il CSSOM è incompleto. L'implicazione pratica è che ogni byte di CSS render-blocking si trova sul percorso critico di ogni Core Web Vital. Un bundle minificato di 100 KB ti fa risparmiare forse 30 ms su un link 4G veloce rispetto a uno non minificato di 150 KB: piccolo per pagina, ma il caso studio di Vodafone ha mostrato un aumento delle vendite dell'8% da un miglioramento LCP del 31%. L'effetto di secondo ordine è ancora più grande: un LCP più veloce alza i punteggi Lighthouse, che alza la visibilità nella ricerca Google per i siti dove i Web Vitals sono un noto segnale di ranking.

Cosa fa davvero un minificatore CSS

Minificatore contro ottimizzatore: la linea sicuro-contro-aggressivo

La documentazione di cssnano distingue tra il suo preset "default" (solo trasformazioni sicure) e il suo preset "advanced" (trasformazioni aggressive che dipendono da assunzioni sul tuo CSS). Il preset default è ciò che attivi senza pensarci; il preset advanced è ciò che attivi dopo un audit, perché alcune ottimizzazioni possono rompere codice che dipende da comportamenti sottili della cascade, prefissi vendor o stranezze del browser. Le trasformazioni avanzate possono riordinare le regole all'interno di un foglio di stile per migliorare la comprimibilità: rischioso se hai fallback intenzionali con proprietà duplicate come display: flex; display: grid;. Possono unire corpi di regola identici in liste di selettori separate da virgola. Possono eliminare le dichiarazioni sovrascritte come codice morto, con la stessa avvertenza sui fallback. Possono normalizzare i valori display, le funzioni transform e gli identificatori custom: translate3d(0,0,0) può semplificarsi a translate(0) se non dipendi dall'effetto collaterale di promozione GPU. Possono eliminare i prefissi vendor inutilizzati basandosi su un target Browserslist. csso (Yandex, 2011) si descrive come un "ottimizzatore strutturale" piuttosto che un puro minificatore, con tre categorie di trasformazione: pulizia, compressione e ristrutturazione. Lightning CSS descrive la stessa divisione: un passaggio "minify" che è sempre sicuro, più un set di trasformazioni consapevoli di targets che compilano il CSS moderno fino a ciò che i browser più vecchi capiscono. La linea onesta: un minificatore è ciò che puoi applicare a qualsiasi file CSS senza pensarci; un ottimizzatore è ciò che applichi con conoscenza della tua codebase.

Breve storia degli strumenti di minificazione CSS

YUI Compressor (2007). Julien Lecomte di Yahoo annunciò YUI Compressor l'11 agosto 2007. La release originale gestiva solo JavaScript; tre giorni dopo, la versione 2.0 aggiunse il supporto CSS integrando un minificatore CSS basato su regex originariamente scritto da Isaac Schlueter per uso personale. YUI Compressor è stato lo standard de facto per diversi anni, specialmente nei mondi Java/Maven e Rails-asset-pipeline; è ancora usato oggi, anche se la libreria YUI stessa fu ritirata da Yahoo nel 2014. Il lato CSS di YUI Compressor è sempre stato basato su regex, non su AST: una decisione di design le cui conseguenze riecheggiano negli strumenti più piccoli lato browser che seguirono.

clean-css (2011). Jakub Pawlowicz pubblicò clean-css sotto l'organizzazione GoalSmashers su GitHub nel 2011, presentandolo come "ottimizzatore CSS veloce ed efficiente per Node.js e il Web." Fu il primo grande minificatore CSS progettato specificamente per l'ecosistema Node.js e divenne il default nelle pipeline Grunt e Gulp. La linea attuale 5.x richiama circa 21 milioni di download settimanali da npm, supporta l'inlining di @import, il rebasing di URL e le source map, e ha un modello a "livelli di ottimizzazione" stratificato che rende esplicita la divisione sicuro-contro-aggressivo. csso (2011) nacque come progetto interno Yandex, pubblicato con copyright 2011 di Sergey Kryzhanovsky basato su un'idea di Vitaly Harisov. cssnano (aprile 2015) di Ben Briggs adottò un approccio diverso: invece di un minificatore monolitico, cssnano è un bundle curato di piccoli plugin PostCSS (~30 nel preset default). Divenne il minificatore CSS dominante nell'ecosistema JavaScript in gran parte grazie a questa componibilità e perché PostCSS stesso, il framework di Andrey Sitnik, prima rilasciato nel novembre 2013, è diventato il substrato per così tanto altro (Autoprefixer, Stylelint, la pipeline di elaborazione di Tailwind). cssnano ora è alla versione 7.x ed è il minificatore CSS di default in css-minimizer-webpack-plugin di webpack, in Next.js e in molti altri default di framework.

Il minificatore CSS di esbuild (2020-2021). Evan Wallace, co-fondatore di Figma, rilasciò esbuild come "un progetto hobby che ho scritto durante le vacanze invernali 2019-2020." Scritto in Go, esbuild era 10-100× più veloce dei bundler basati su JavaScript dell'epoca. Il supporto CSS è maturato attraverso il 2021; ora è onnipresente come minificatore sottostante in Vite, in tsup, in innumerevoli template di framework. Lightning CSS (2021/2022). Devon Govett, creatore di Parcel, annunciò Parcel CSS nel 2021: un parser, transformer, bundler e minificatore CSS scritto da zero in Rust. La proposta era velocità (10-100× più veloce dei JS-based esistenti) più correttezza (un vero parser che segue la specifica CSS, non pattern-matching regex) più compilazione consapevole dei target (riduci il CSS moderno a ciò che i browser più vecchi capiscono, come Babel per JavaScript). Nel 2022 il progetto fu rinominato Lightning CSS per dissociarlo da Parcel come strumento standalone. Ora è la pipeline CSS moderna raccomandata di Vite, il default in Parcel stesso e un'opzione in css-minimizer-webpack-plugin. Il motore Oxide di prossima generazione di Tailwind lo integra.

La pipeline CSS moderna

I progetti web moderni scrivono raramente CSS grezzo in un foglio di stile. Sass (Hampton Catlin e Natalie Weizenbaum, prima rilasciata 2006), Less (Alexis Sellier, 2009) e Stylus (TJ Holowaychuk, 2010) si trovano all'inizio della pipeline, aggiungendo variabili, annidamento, mixin, funzioni e parziali. Il compilatore emette CSS vanilla, che poi fluisce attraverso PostCSS per trasformazioni come Autoprefixer (applicazione di prefissi vendor basata su Browserslist), srotolamento di nested-CSS e down-leveling di CSS moderno. Solo dopo tutto questo gira il minificatore, sul CSS finale piatto. I bundler moderni distribuiscono la minificazione CSS di default: webpack 5 include css-minimizer-webpack-plugin (cssnano sotto il cofano di default, con cssoMinify, cleanCssMinify, esbuildMinify e lightningCssMinify tutti selezionabili); Vite usa esbuild per CSS di default e supporta Lightning CSS come opt-in; Parcel usa Lightning CSS; Next.js, Remix, Astro, SvelteKit e Nuxt aggregano tutti la minificazione nelle build di produzione senza intervento dello sviluppatore. Il risultato è che per chiunque usi una pipeline di build moderna, la minificazione CSS avviene automaticamente.

Ma non tutti usano una pipeline di build. Molti siti WordPress, pagine HTML scritte a mano, siti statici Jekyll/Hugo/Eleventy senza una toolchain JS e progetti una tantum distribuiscono CSS che non è mai stato vicino a webpack. Per quelli, un minificatore in-browser è la strada di minor resistenza: incolla il CSS dentro, copia il risultato fuori, salva il deploy.

CSS critico

Una tecnica complementare che vale la pena conoscere: il CSS critico è la pratica di identificare il sottoinsieme di stili necessari per renderizzare il viewport above-the-fold, inserendo quel sottoinsieme direttamente in un blocco <style> nell'head del documento, e differendo il resto del foglio di stile a un caricamento non-blocking. Fatto bene, la pagina disegna il suo viewport iniziale al primo round trip di rete, senza alcuna richiesta separata per un foglio di stile esterno. Filament Group ha costruito gli strumenti canonici: Scott Jehl ha pubblicato loadCSS il 14 luglio 2014, una piccola utility JavaScript che carica un foglio di stile in modo asincrono impostando il suo attributo media su un valore non corrispondente, poi riportandolo a all una volta che il file è scaricato. Il pattern alla fine è diventato abbastanza standard che i browser hanno aggiunto <link rel="preload" as="style" onload="this.rel='stylesheet'"> come modo più diretto di esprimerlo. Jason Miller (creatore di Preact) ha rilasciato Critters sotto GoogleChromeLabs nel 2018 come alternativa più veloce: invece di eseguire un browser headless per ispezionare la pagina renderizzata, Critters fa analisi statica. Il repository di Critters è stato archiviato nel 2024 con il fork attivamente mantenuto che ora vive come Beasties sotto il team Nuxt. Tutti questi strumenti dipendono dal fatto che il CSS sottostante sia ben minificato: ogni byte risparmiato nel foglio di stile sorgente fluisce in un inline critico più piccolo.

Gli hack legacy sono spariti

Tutti i browser moderni analizzano il CSS secondo la stessa specifica. Gli hack storici che una volta rendevano la minificazione CSS rischiosa sono essenzialmente spariti: l'hack * html mirava a IE6 sfruttando un bug del parser; l'hack underscore _property: value mirava a IE6 e precedenti; *property: value (con * prima del nome della proprietà) mirava a IE7 e precedenti; i commenti condizionali <!--[if IE 6]> ti permettevano di servire fogli di stile diversi a versioni IE specifiche, ma Microsoft ha rimosso questa funzionalità in IE10. IE11 ha raggiunto il fine vita il 15 giugno 2022 per la maggior parte delle versioni Windows 10 consumer. Nel 2026 questi hack sono curiosità storiche e un minificatore CSS non ha più bisogno di pensarci. Un minificatore moderno che elimina lo spazio in modo identico tra i browser e applica le trasformazioni definite dalla specifica descritte sopra è sicuro.

Cosa fa (e non fa) questo strumento

Questo strumento è un minificatore in-browser a singolo file: circa 30 righe di JavaScript. Tokenizza i literal stringa in placeholder così che i passaggi successivi non possano corrompere il loro contenuto, rimuove i commenti /* ... */, collassa lo spazio attorno a {, }, :, ;, ,, >, ~, +, rimuove il punto e virgola finale prima di }, collassa sequenze di spazio bianco in un singolo spazio, accorcia i colori esadecimali a sei cifre nella forma a tre cifre quando ogni coppia di cifre è identica, ed elimina l'unità dai valori zero per px, em, rem, %, pt, ex, ch, vw, vh, vmin, vmax. Non analizza il CSS in un AST: è un passaggio regex. Non collassa longhand in shorthand. Non unisce o de-duplica i selettori. Non riordina le dichiarazioni. Non converte rgb() in hex o nomi di colori in hex. Non minuscolizza le keyword. Non preserva i commenti /*! importanti: tutti i commenti sono eliminati allo stesso modo; se hai header di licenza da mantenere, reincollali dopo la minificazione. Non emette una source map. L'inquadramento onesto: incolla il CSS uscito dal tuo editor o dalla tua mano, ricevi una versione spogliata che è tipicamente il 20-40% più piccola in byte grezzi, e usalo come artefatto di deploy rapido per siti costruiti a mano. Per progetti con una pipeline di build, usa cssnano o Lightning CSS in quella pipeline; per quelli che non ce l'hanno, questo strumento elimina l'attrito.

Perché "solo browser" conta qui

Ogni minificatore CSS basato sul web ha la stessa scelta architetturale: fare il lavoro su un server, o farlo nel browser dell'utente. L'elaborazione lato server richiede di caricare il foglio di stile sulla rete, il che significa che una copia di quel CSS resta nei log del server, possibilmente in una cache CDN, possibilmente in una pipeline di analytics, possibilmente in un backup. Per la maggior parte del CSS questo è innocuo. Per strumenti interni, stili di prodotto non rilasciati o fogli di stile che contengono selettori che rivelano tassonomie di classi interne (.admin-panel-internal-debug-info), non lo è. Anche per il CSS ordinario di un sito di marketing, uno sviluppatore che fa l'audit di ciò che effettivamente manda in rete può ragionevolmente preferire che il work-in-progress resti sulla sua macchina. Un minificatore puramente basato sul browser, JavaScript che gira nella tua tab e non fa mai una richiesta di rete dopo il caricamento iniziale della pagina, scavalca la questione. Puoi verificarlo: apri il pannello Network di DevTools, incolla il CSS, clicca Minify, e guarda se c'è qualche richiesta in uscita. Non ce ne sarà. Meglio ancora, disconnettiti da internet (o abilita la modalità aereo) dopo che la pagina si carica e lo strumento continuerà a funzionare, che è la prova empirica più forte che nulla viene caricato.

Domande frequenti

Quanto sarà più piccolo il mio CSS?

CSS formattato a mano con commenti e indentazione tipicamente si restringe del 20-40% in byte grezzi. Il CSS che è già stato compilato da Sass/Less e formattato leggermente si restringe meno. Il CSS che è stato elaborato attraverso PostCSS o Autoprefixer spesso ha già commenti minimi e si restringe meno. La dimensione dopo la compressione Brotli al margine della CDN si restringerà ulteriormente: Brotli su CSS minificato fa risparmiare comunque un altro 5-15% rispetto a Brotli su CSS non minificato, a seconda di quanto ripetitivo era lo spazio originale.

L'output minificato romperà qualcosa?

Per CSS ordinario, no: le trasformazioni sono sicure rispetto alla specifica. I due casi che vale la pena controllare da soli: (1) i valori zero dentro calc(), min(), max(), clamp() e proprietà custom CSS non dovrebbero essere unit-stripped perché le regole di aritmetica tipata richiedono un'unità; il passaggio regex di questo strumento è conservativo ma se hai calc(0px + 10%) nel tuo CSS, dai un occhio all'output. (2) Se il tuo foglio di stile ha fallback con proprietà duplicate come display: flex; display: grid;, questo strumento preserva entrambe, ma minificatori avanzati come cssnano con il preset advanced rimuoverebbero la prima. Se dipendi da comportamenti specifici del browser per la cascade, fai l'audit prima del deploy.

Preserva gli header di licenza?

No. I minificatori di produzione onorano la convenzione che i commenti che iniziano con /*! (con un punto esclamativo) sono preservati come "importanti", di solito per header di copyright e avvisi di licenza. Questo strumento elimina tutti i commenti allo stesso modo. Se distribuisci CSS che ha bisogno di un header di licenza (MIT, GPL, attribuzione del codice BSD), reincolla l'header nell'output manualmente. Per una pipeline che ha bisogno di preservazione automatica, usa cssnano o Lightning CSS invece.

Dovrei usarlo se ho già una pipeline di build?

Probabilmente no: il tuo bundler lo sta facendo per te. webpack 5 distribuisce css-minimizer-webpack-plugin con cssnano sotto il cofano; Vite usa esbuild per la minificazione CSS di default; Parcel usa Lightning CSS. Questo strumento è per i casi che la tua pipeline di build non copre: HTML scritto a mano, temi WordPress distribuiti senza una toolchain Node, generatori di siti statici che non aggregano la minificazione, file CSS una tantum per un template email o una demo veloce. Per quelli, uno strumento browser paste-in è la strada di minor resistenza.

I miei file vengono caricati?

No. Il minificatore è JavaScript che gira nel tuo browser. Il CSS che incolli non attraversa mai la rete: verifica nel pannello Network di DevTools mentre clicchi Minify, oppure metti la pagina offline dopo che si è caricata e conferma che lo strumento continui a funzionare. Fogli di stile interni, stili di prodotto non rilasciati e CSS che rivelano tassonomie di classi interne restano sul tuo dispositivo.

Posso non-minificare l'output in seguito?

Non esattamente: i commenti e lo spazio originale sono andati per sempre, è il punto. Ma puoi formattare il CSS minificato per renderlo di nuovo leggibile. Pretty-printer come Prettier (con il plugin CSS), il comando Format Document integrato in VS Code, o uno qualunque degli strumenti online "CSS beautifier" reinseriranno indentazione e a-capo. Non possono recuperare commenti cancellati. Conserva sempre la tua sorgente non minificata nel version control come la forma canonica.

Strumenti correlati