Minification è il processo di rimozione di tutti i caratteri non essenziali dal codice sorgente: spazi, tabulazioni, interruzioni di riga e commenti. La minification riduce la dimensione dei file JavaScript, CSS e HTML senza modificare la logica di esecuzione del programma. Secondo MDN Web Docs, la minification può ridurre la dimensione del file del 50–70%, influenzando direttamente la velocità di caricamento delle applicazioni e il First Contentful Paint (FCP).
Punti chiave
Minification è una trasformazione automatica del codice sorgente che rimuove tutti i caratteri che non influenzano l'esecuzione del programma. Spazi, tabulazioni, caratteri di nuova riga, commenti e parentesi ridondanti vengono rimossi o abbreviati. La minification viene applicata a JavaScript, CSS, HTML e, meno frequentemente, alle configurazioni JSON prima del deployment in produzione.
L'obiettivo principale della minification è ridurre la dimensione dei file trasmessi sulla rete. Un file JavaScript di 300 KB dopo la minification può occupare 120–150 KB, riducendo il tempo di caricamento di 200–400 ms su una connessione 3G lenta. Google PageSpeed Insights e Lighthouse raccomandano direttamente di minificare il codice: è uno dei criteri di valutazione delle prestazioni e dei Core Web Vitals.
La minification è parte integrante della pipeline di build. Dopo la transpilazione con TypeScript o Babel, il codice passa attraverso Tree Shaking (rimozione delle funzioni inutilizzate), poi attraverso un minificatore, e solo successivamente viene assemblato nel bundle finale. Nei bundler moderni (Webpack, Rollup, esbuild), la minification viene eseguita da plugin nella fase finale del build.
| Elemento | Esempio (prima) | Esempio (dopo) | Risparmio |
|---|---|---|---|
| Spazi e tabulazioni | let x = 5; | let x=5; | ~10–20% |
| Interruzioni di riga | \n tra le righe | tutto su una riga | ~2–5% |
| Commenti | // comment | rimosso | ~5–30% |
| Parentesi ridondanti | if ((x > 0)) | if(x>0) | ~1–3% |
Rimozione di spazi e interruzioni di riga è la tecnica più semplice e ovvia. Il parser del minificatore attraversa l'AST (Abstract Syntax Tree) e rimuove tutti i caratteri di spaziatura che non fanno parte di letterali di stringa. La maggior parte dei minificatori combina inoltre gli operatori in un'unica riga, fornendo un risparmio aggiuntivo durante la compressione con GZip o Brotli.
Sostituzione dei nomi delle variabili (mangling) è una tecnica più aggressiva. Le variabili locali e i parametri delle funzioni vengono rinominati in identificatori di una sola lettera: a, b, c. Ciò riduce la dimensione di un ulteriore 15–30%. Terser ed esbuild supportano il mangling con l'opzione di preservare determinati nomi (ad esempio, API pubblica tramite mangle.props.reserved).
Dead code elimination (DCE) rimuove i rami di codice che non vengono mai eseguiti. Il minificatore analizza le condizioni che sono sempre false (if (false)) e rimuove i blocchi corrispondenti. Un'analisi più avanzata viene eseguita nella fase di Tree Shaking prima della minification, ma la DCE a livello di minificatore rileva casi locali di codice morto non rilevati a livello di modulo.
Mangling rinomina le variabili locali e i parametri delle funzioni in identificatori brevi (una o due lettere). Terser esegue il mangling basato sullo scope: le variabili all'interno di una singola funzione ricevono nomi brevi unici che non entrano in conflitto con gli scope esterni. L'opzione mangle.reserved consente di preservare determinati nomi — ad esempio, le API pubbliche delle librerie.
Il mangling non influisce sulle variabili globali, sulle proprietà degli oggetti (a meno che mangle.props non sia abilitato) né sui nomi delle classi utilizzati con new. Per proteggere l'API pubblica di una libreria dal mangling, utilizzare mangle.props.reserved con espressioni regolari: reserved: ["_prop", /^private_/]. Senza questa impostazione, il mangling può rompere una libreria se il codice esterno accede alle proprietà degli oggetti per nome.
// Codice sorgente
function calculateTotal(price, tax) {
var result = price + (price * tax);
// Restituire l'importo totale
return result;
}
var total = calculateTotal(100, 0.2);
console.log(total);// Dopo minification con Terser
function calculateTotal(a, b){return a + a * b}
var c = calculateTotal(100, .2);
console.log(c);Nel secondo esempio, Terser ha rimosso commenti, spazi e interruzioni di riga, rinominando price in a, tax in b, result in c. La dimensione è passata da 197 caratteri a 79 — un risparmio del 60%. Allo stesso tempo, la funzionalità del codice è completamente preservata: calculateTotal(100, 0.2) restituisce 120.
Terser è il minificatore JavaScript standard nell'ecosistema Webpack e nella maggior parte dei bundler moderni. Terser supporta la sintassi ES6+ (funzioni freccia, async/await, spread), il mangling con protezione dell'API pubblica, le source maps e l'esecuzione parallela con il numero di CPU. Dalla versione 5.16, Terser include ottimizzazioni per TypeScript — rimozione degli import solo tipo e delle interfacce.
esbuild è un minificatore scritto in Go, integrato nell'omonimo bundler. esbuild esegue la minification 10–100 volte più velocemente di Terser grazie al codice nativo e all'elaborazione parallela. Tuttavia, esbuild supporta meno ottimizzazioni: non esegue il mangling con conservazione delle proprietà, non rimuove gli import solo tipo e ottimizza le espressioni in modo meno aggressivo.
// webpack.config.js — configurazione di TerserPlugin
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
dead_code: true,
},
mangle: {
reserved: ["React", "Component"],
},
output: {
comments: false,
},
},
parallel: true,
}),
],
},
};La configurazione di TerserPlugin include tre blocchi principali. compress gestisce l'ottimizzazione delle espressioni: drop_console rimuove console.log, drop_debugger rimuove debugger, dead_code rimuove i rami irraggiungibili. mangle controlla la ridenominazione delle variabili con reserved per proteggere i nomi pubblici. parallel abilita il multithreading con il numero di CPU.
// esbuild: comando CLI per minification JS e CSS
// esbuild app.js --bundle --minify --outfile=dist/app.min.js
// esbuild app.css --bundle --minify --outfile=dist/app.min.css
const esbuild = require("esbuild");
esbuild.build({
entryPoints: ["src/app.js", "src/styles.css"],
bundle: true,
minify: true,
sourcemap: true,
target: ["es2015"],
outdir: "dist",
}).catch(() => process.exit(1));L'API esbuild accetta una configurazione in una riga. minify: true abilita la minification sia di JS che di CSS. sourcemap: true genera mappe di codice per il debug. target definisce il livello ES minimo — esbuild transpila automaticamente il codice moderno per la versione selezionata. esbuild è particolarmente efficace per progetti in cui il tempo di build è critico: pipeline CI/CD, Hot Module Replacement e prototipi rapidi.
React Native utilizza Metro Bundler — il proprio bundler che include la minification basata su Terser. In modalità produzione, Metro applica automaticamente la minification al bundle JavaScript dell'applicazione. La configurazione della minification in Metro viene impostata tramite metro.config.js nella sezione transformer.minifierConfig. Inoltre, inline-require può essere disabilitato per ridurre la dimensione del bundle su iOS.
WebView nelle applicazioni mobili beneficia anch'essa della minification. HTML, CSS e JS caricati in WebView devono essere minificati prima di essere incorporati nell'applicazione o caricati dal server. Per le risorse locali (Assets), la minification è particolarmente importante — la dimensione di APK/IPA influisce direttamente sulla conversione delle installazioni negli app store.
Hermes è un motore JavaScript per React Native sviluppato da Facebook. Hermes esegue la compilazione Ahead-of-Time (AOT) in bytecode, riducendo il tempo di avvio dell'applicazione del 30–50%. Per Hermes, la minification del bundle JavaScript viene eseguita prima della compilazione in bytecode utilizzando Terser. Hermes supporta il proprio formato HBC (Hermes Bytecode), ma la fase di minification JS rimane necessaria.
// metro.config.js — configurazione della minification
const defaultConfig = require("metro-config/src/defaults");
module.exports = require("metro-config").mergeConfig(
defaultConfig,
{
transformer: {
minifierConfig: {
compress: {
drop_console: true,
},
mangle: {
safari10: true,
},
},
},
}
);Metro con minifierConfig.drop_console rimuove tutti i console.log dal bundle di produzione di React Native. Il parametro mangle.safari10 impedisce la ridenominazione degli identificatori che rompono Safari 10 (iOS 10). Questo è particolarmente importante per le applicazioni che supportano dispositivi più vecchi come iPad e iPhone 5s con iOS 10/11.
Minification e compressione (gzip, brotli) sono diversi stadi di ottimizzazione. La minification opera a livello di codice sorgente e riduce il numero di caratteri prima dell'invio al server. La compressione opera a livello di protocollo di trasporto e viene applicata dal server (nginx, Apache, CDN) durante la trasmissione del file al client. La minification riduce la dimensione prima della compressione, producendo un doppio effetto: gzip comprime dati già ridotti.
Un file JavaScript di 300 KB dopo la minification — 120 KB, dopo gzip — 35–40 KB. Se si applica solo gzip al file non minificato, la dimensione sarà di 55–70 KB. Minification + gzip dà un risultato del 30–40% migliore rispetto al solo gzip. Brotli (livello 6) comprime in modo aggiuntivo del 15–20% più efficientemente di gzip dopo la minification.
| Metodo | Livello | Dimensione file | Riduzione |
|---|---|---|---|
| File originale | — | 300 KB | 0% |
| Dopo minification | Codice | 120 KB | 60% |
| Dopo gzip (senza minification) | Trasporto | 65 KB | 78% |
| Minification + gzip | Codice + Trasporto | 38 KB | 87% |
| Minification + Brotli | Codice + Trasporto | 30 KB | 90% |
Domande frequenti
UglifyJS è uno strumento di minification obsoleto che non supporta la sintassi ES6+. Terser è un fork di UglifyJS con supporto per JavaScript moderno. Tutti i bundler moderni (Webpack 5, Rollup, esbuild) utilizzano Terser o propri minificatori, mentre UglifyJS è utilizzato solo in progetti legacy.
Source maps sono file .map separati non inclusi nel bundle di produzione. Il server dovrebbe fornire le source maps solo agli sviluppatori autorizzati (tramite l'intestazione Authorization). In produzione, le source maps non vengono caricate dal browser dell'utente, quindi non influiscono sulla dimensione del bundle.
Rischio di rottura esiste con un mangling aggressivo che trasforma i nomi delle proprietà degli oggetti. Se il codice accede a elementi DOM tramite data-attributes o utilizza stringhe JSON per denominare i campi, il mangling può rinominare le proprietà pubbliche. La soluzione è escludere tramite mangle.reserved o disabilitare il mangling per determinati namespace.
La minification CSS fornisce un guadagno inferiore (15–25%) rispetto alla minification JS, ma è obbligatoria per la conformità ai Core Web Vitals. I minificatori CSS rimuovono gli spazi, uniscono selettori identici, abbreviano i colori esadecimali (#ff0000 → #f00) e rimuovono @keyframes inutilizzati. CleanCSS ed esbuild sono strumenti popolari per la minification CSS.
Source maps (file .map) collegano il codice minificato alla sorgente originale. In Chrome DevTools e Safari Web Inspector, quando le source maps sono abilitate, vengono visualizzati i file originali. Per un corretto funzionamento, le source maps devono essere caricate sul server (anche in produzione) e abilitate tramite gli strumenti per sviluppatori.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche