Minifikacja — proces usuwania z kodu źródłowego wszystkich nieistotnych znaków: spacji, tabulacji, znaków nowej linii i komentarzy. Minifikacja zmniejsza rozmiar plików JavaScript, CSS i HTML bez zmiany logiki działania programu. Według MDN Web Docs, minifikacja może zmniejszyć rozmiar pliku o 50–70%, co bezpośrednio wpływa na szybkość ładowania aplikacji i First Contentful Paint (FCP).
Najważniejsze
Minifikacja — automatyczne przekształcanie kodu źródłowego, podczas którego usuwane są wszystkie znaki niemające wpływu na wykonanie programu. Spacje, tabulacje, znaki nowej linii, komentarze i zbędne nawiasy są usuwane lub skracane. Minifikacja jest stosowana do JavaScript, CSS, HTML i rzadziej do konfiguracji JSON przed wdrożeniem na produkcję.
Głównym celem minifikacji jest zmniejszenie rozmiaru plików przesyłanych przez sieć. Plik JavaScript o rozmiarze 300 KB po minifikacji może zajmować 120–150 KB, co skraca czas ładowania o 200–400 ms przy wolnym połączeniu 3G. Google PageSpeed Insights i Lighthouse bezpośrednio zalecają minifikację kodu: to jeden z kryteriów oceny wydajności i Core Web Vitals.
Minifikacja jest nieodłączną częścią potoku budowania (build pipeline). Po transpilacji TypeScript lub Babel, kod przechodzi przez Tree Shaking (usuwanie nieużywanych funkcji), następnie przez minifikator, a dopiero potem jest składany w finalny bundle. W nowoczesnych bundlerach (Webpack, Rollup, esbuild) minifikacja jest wykonywana przez wtyczki na końcowym etapie budowania.
| Element | Przykład (przed) | Przykład (po) | Oszczędność |
|---|---|---|---|
| Spacje i tabulacje | let x = 5; | let x=5; | ~10–20% |
| Znaki nowej linii |
między wierszami | wszystko w jednej linii | ~2–5% |
| Komentarze | // comment | usunięte | ~5–30% |
| Zbędne nawiasy | if ((x > 0)) | if(x>0) | ~1–3% |
Usuwanie spacji i znaków nowej linii — najprostsza i najbardziej oczywista technika. Parser minifikatora przechodzi przez AST (Abstract Syntax Tree) i usuwa wszystkie białe znaki, które nie są częścią literałów łańcuchowych. Większość minifikatorów dodatkowo łączy operatory w jednej linii, co daje dodatkową oszczędność przy kompresji przez GZip lub Brotli.
Zastępowanie nazw zmiennych krótkimi (mangling) — bardziej agresywna technika. Zmienne lokalne i parametry funkcji są przemianowywane na jednoliterowe identyfikatory: a, b, c. Zmniejsza to rozmiar dodatkowo o 15–30%. Terser i esbuild obsługują mangling z opcją zachowania określonych nazw (np. publicznego API przez mangle.props.reserved).
Dead code elimination (DCE) — usuwanie gałęzi kodu, które nigdy nie są wykonywane. Minifikator analizuje warunki, które są zawsze fałszywe (if (false)) i usuwa odpowiednie bloki. Bardziej zaawansowana analiza jest wykonywana na etapie Tree Shaking przed minifikacją, ale DCE na poziomie minifikatora wyłapuje lokalne przypadki martwego kodu niewykryte na poziomie modułów.
Mangling — przemianowywanie zmiennych lokalnych i parametrów funkcji na krótkie identyfikatory (jedna-dwie litery). Terser wykonuje mangling w oparciu o scope: zmienne w obrębie jednej funkcji otrzymują unikalne krótkie nazwy, nie kolidujące z zewnętrznymi scope. Opcja mangle.reserved pozwala zachować określone nazwy — na przykład publiczne API bibliotek.
Mangling nie wpływa na zmienne globalne, właściwości obiektów (jeśli nie włączono mangle.props) i nazwy klas używane z new. Aby chronić publiczne API bibliotek przed manglingiem, należy użyć mangle.props.reserved z wyrażeniami regularnymi: reserved: ["_prop", /^private_/]. Bez tego ustawienia mangling może uszkodzić bibliotekę, jeśli zewnętrzny kod odwołuje się do właściwości obiektu po nazwie.
// Kod źródłowy
function calculateTotal(price, tax) {
var result = price + (price * tax);
// Zwracamy sumę końcową
return result;
}
var total = calculateTotal(100, 0.2);
console.log(total);// Po minifikacji Terser
function calculateTotal(a, b){return a + a * b}
var c = calculateTotal(100, .2);
console.log(c);W drugim przykładzie Terser usunął komentarze, spacje i znaki nowej linii, przemianował price na a, tax na b, result na c. Rozmiar zmniejszył się z 197 znaków do 79 — oszczędność 60%. Przy tym funkcjonalność kodu została w pełni zachowana: calculateTotal(100, 0.2) zwraca 120.
Terser — standardowy minifikator JavaScript w ekosystemie Webpack i większości nowoczesnych bundlerów. Terser obsługuje składnię ES6+ (funkcje strzałkowe, async/await, spread), mangling z ochroną publicznego API, source maps i równoległe uruchamianie poprzez liczbę CPU. Od wersji 5.16 Terser zawiera optymalizacje dla TypeScript — usuwanie type-only importów i interfejsów.
esbuild — minifikator napisany w Go, wbudowany w bundler o tej samej nazwie. esbuild wykonuje minifikację 10–100 razy szybciej niż Terser dzięki natywnemu kodowi i równoległemu przetwarzaniu. Jednak esbuild obsługuje mniej optymalizacji: nie wykonuje manglingu z zachowaniem właściwości, nie usuwa type-only importów i mniej agresywnie optymalizuje wyrażenia.
// webpack.config.js — konfiguracja 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,
}),
],
},
};Konfiguracja TerserPlugin zawiera trzy kluczowe bloki. compress odpowiada za optymalizację wyrażeń: drop_console usuwa console.log, drop_debugger usuwa debugger, dead_code usuwa nieosiągalne gałęzie. mangle zarządza przemianowywaniem zmiennych z reserved do ochrony publicznych nazw. parallel włącza wielowątkowość na liczbę CPU.
// esbuild: polecenie CLI do minifikacji JS i 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));esbuild API przyjmuje konfigurację w jednej linii. minify: true włącza minifikację zarówno JS, jak i CSS. sourcemap: true generuje mapy kodu do debugowania. target określa minimalny poziom ES — esbuild automatycznie transpiluje nowoczesny kod do wybranej wersji. esbuild jest szczególnie efektywny w projektach, gdzie czas budowania jest krytyczny: pipeline'y CI/CD, Hot Module Replacement i szybkie prototypy.
React Native używa Metro Bundler — własnego bundlera, który zawiera minifikację opartą na Terser. W trybie produkcyjnym Metro automatycznie stosuje minifikację do bundla JavaScript aplikacji. Konfiguracja minifikacji w Metro jest ustawiana przez metro.config.js w sekcji transformer.minifierConfig. Dodatkowo można wyłączyć inline-require, aby zmniejszyć rozmiar bundla na iOS.
WebView w aplikacjach mobilnych również zyskuje na minifikacji. HTML, CSS i JS ładowane w WebView powinny przejść minifikację przed osadzeniem w aplikacji lub załadowaniem z serwera. Dla zasobów lokalnych (Assets) minifikacja jest szczególnie ważna — rozmiar APK/IPA bezpośrednio wpływa na konwersję instalacji w sklepach aplikacji.
Hermes — silnik JavaScript dla React Native, opracowany przez Facebook. Hermes wykonuje kompilację Ahead-of-Time (AOT) kodu bajtowego, co skraca czas uruchamiania aplikacji o 30–50%. Dla Hermesa minifikacja bundla JavaScript jest wykonywana przed kompilacją do kodu bajtowego przez Terser. Hermes obsługuje własny format HBC (Hermes Bytecode), ale etap minifikacji JS pozostaje niezbędny.
// metro.config.js — konfiguracja minifikacji
const defaultConfig = require("metro-config/src/defaults");
module.exports = require("metro-config").mergeConfig(
defaultConfig,
{
transformer: {
minifierConfig: {
compress: {
drop_console: true,
},
mangle: {
safari10: true,
},
},
},
}
);Metro z minifierConfig.drop_console usuwa wszystkie console.log z produkcyjnego bundla React Native. Parametr mangle.safari10 zapobiega przemianowywaniu identyfikatorów, które mogą uszkodzić Safari 10 (iOS 10). Jest to szczególnie ważne w aplikacjach obsługujących stare urządzenia iPad i iPhone 5s z iOS 10/11.
Minifikacja i kompresja (gzip, brotli) to różne etapy optymalizacji. Minifikacja działa na poziomie kodu źródłowego i zmniejsza liczbę znaków przed wysłaniem na serwer. Kompresja działa na poziomie protokołu transportowego i jest stosowana przez serwer (nginx, Apache, CDN) podczas przesyłania pliku do klienta. Minifikacja zmniejsza rozmiar przed kompresją, co daje podwójny efekt: gzip kompresuje już skrócone dane.
Rozmiar pliku JavaScript 300 KB po minifikacji — 120 KB, po gzip — 35–40 KB. Jeśli zastosować tylko gzip do niezminifikowanego pliku, rozmiar wyniesie 55–70 KB. Minifikacja + gzip daje o 30–40% lepszy wynik niż sam gzip. Brotli (poziom 6) kompresuje dodatkowo o 15–20% wydajniej niż gzip po minifikacji.
| Metoda | Poziom | Rozmiar pliku | Redukcja |
|---|---|---|---|
| Oryginalny plik | — | 300 KB | 0% |
| Po minifikacji | Kod | 120 KB | 60% |
| Po gzip (bez minifikacji) | Transport | 65 KB | 78% |
| Minifikacja + gzip | Kod + Transport | 38 KB | 87% |
| Minifikacja + Brotli | Kod + Transport | 30 KB | 90% |
Często zadawane pytania
UglifyJS — to przestarzałe narzędzie do minifikacji, nieobsługujące składni ES6+. Terser to fork UglifyJS z obsługą nowoczesnego JavaScript. Wszystkie nowoczesne bundlery (Webpack 5, Rollup, esbuild) używają Terser lub własnych minifikatorów, a UglifyJS jest stosowany tylko w projektach legacy.
Source maps — to osobne pliki .map, nie dołączane do produkcyjnego bundla. Serwer powinien udostępniać source maps tylko autoryzowanym programistom (poprzez nagłówek Authorization). W produkcji source maps nie są ładowane przez przeglądarkę użytkownika, więc nie wpływają na rozmiar bundla.
Ryzyko uszkodzenia istnieje przy agresywnym manglingu z przekształcaniem nazw właściwości obiektów. Jeśli kod odwołuje się do elementów DOM przez atrybuty data lub używa JSON-stringów do nazywania pól, mangling może przemianować publiczne właściwości. Rozwiązaniem jest exclude przez mangle.reserved lub wyłączenie manglingu dla określonych przestrzeni nazw.
Minifikacja CSS daje mniejszy zysk (15–25%) niż minifikacja JS, ale jest obowiązkowa dla zgodności z Core Web Vitals. Minifikatory CSS usuwają spacje, łączą identyczne selektory, skracają kolory hex (#ff0000 → #f00) i usuwają nieużywane @keyframes. CleanCSS i esbuild to popularne narzędzia do minifikacji CSS.
Source maps (pliki .map) łączą zminifikowany kod z oryginalnym. W Chrome DevTools i Safari Web Inspector przy włączonych source maps wyświetlane są oryginalne pliki. Do prawidłowego działania source maps muszą być załadowane na serwer (nawet produkcyjny) i włączone przez narzędzia deweloperskie.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również