Skip to content
Powrót do bloga
Poradniki

Przewodnik po minifikacji kodu: CSS, JS i HTML

Czym jest minifikacja kodu, jak minifikować CSS, JS i HTML oraz dlaczego minify i gzip/brotli to co innego. Poznaj właściwą kolejność i minifikuj kod za darmo online.

15 min czytania

Przewodnik po minifikacji kodu: CSS, JS i HTML

Minifikacja kodu usuwa ze źródła CSS, JavaScript i HTML znaki, których maszyna nie potrzebuje (białe znaki, komentarze, podziały wierszy), i przepisuje rozwlekłe konstrukcje na krótsze odpowiedniki. Zachowanie pozostaje takie samo; plik po prostu staje się mniejszy i ładuje się szybciej.

Jedno trzeba sobie wyjaśnić na samym początku: minifikacja to nie kompresja. Minify działa na kodzie źródłowym i usuwa redundancję składniową. Gzip i Brotli działają na bajtach w transmisji i kodują powtarzające się wzorce. Pracują na różnych etapach, atakują różne rodzaje redundancji i nakładają się na siebie, więc warto minifikować nawet wtedy, gdy serwer już udostępnia treść przez Brotli. Ten przewodnik wyjaśnia dlaczego.

Chcesz coś skompresować od razu? Przejdź prosto do minifikatora CSS, minifikatora JavaScript albo minifikatora HTML; każdy z nich działa w całości w przeglądarce. Ale zrozumienie mechaniki pozwala zdecydować, gdzie kompresować i czy w ogóle trzeba robić to ręcznie. Reszta przewodnika omawia, co właściwie robi minifikacja, jak minifikuje się CSS, JS i HTML, jak minify łączy się z gzip i Brotli, kiedy narzędzie do budowania już to ogarnia oraz jak source mapy utrzymują zminifikowany kod w stanie nadającym się do debugowania.

Czym jest minifikacja (i czym nie jest)

Minifikacja robi dwie rzeczy. Usuwa znaki, które nie niosą znaczenia dla parsera, i przepisuje źródło na krótszą formę o dokładnie tym samym znaczeniu. Wynik jest w pełni równoważny dla maszyny i niemal nieczytelny dla człowieka. Sposób działania kodu się nie zmienia; zmienia się tylko jego powierzchnia.

Ten ostatni punkt to niezmiennik, którego warto się trzymać przez resztę przewodnika: minify edytuje wyłącznie powierzchnię źródła (białe znaki, komentarze, nazwy identyfikatorów, nadmiarową składnię), nigdy zachowanie ani wynik. To lustrzane odbicie formatowania. Formatowanie dodaje białe znaki, by kod był czytelny; minifikacja usuwa je, by kod był mały. Obie operacje leżą na tej samej osi „równoważności semantycznej”, tyle że skierowane są w przeciwne strony.

Ludzie nieustannie mylą trzy operacje, które brzmią podobnie. Ta tabela je rozdziela:

WymiarFormat (upiększanie)MinifyKompresja (gzip/Brotli)
Co zmieniaDodaje białe znaki, podziały wierszy, wcięciaUsuwa białe znaki i komentarze, skraca składnięKodowanie powtarzających się wzorców na poziomie bajtów
Która warstwaKod źródłowyKod źródłowyTransmisja / przechowywanie
Nadal kod źródłowy?Tak (czytelny)Tak (wykonywalny, trudny do czytania)Nie (binarny, trzeba zdekodować)
Kto to robiProgramista / edytorNarzędzie budujące / minifikatorSerwer + przeglądarka
Odwracalne?SemantycznieSemantycznie (zachowanie bez zmian)W pełni (dekompresja przywraca bajty)

Format i minify leżą na jednej osi, osi równoważności semantycznej. Kompresja leży na zupełnie innej. Sformatowany plik i zminifikowany plik to oba poprawny kod źródłowy; plik skompresowany to binarny blok danych, który trzeba zdekodować, zanim cokolwiek będzie mogło się uruchomić.

Tu wkrada się kosztowne nieporozumienie: „mój serwer i tak robi gzip, więc minifikacja nie ma sensu”. Ma sens, a liczby z dalszej części przewodnika pokazują dlaczego. Minifikacja i kompresja usuwają różną redundancję, więc wykonanie jednej nie czyni drugiej zbędną. Warto o tym pamiętać przy kolejnych językach.

Pomaga zastanowić się, dlaczego bajty, które usuwa minifikator, w ogóle istnieją. Piszesz białe znaki, komentarze i opisowe nazwy dla siebie i kolegów z zespołu, bo to dzięki nim kod da się przeglądać i utrzymywać. Maszyna, która parsuje twój CSS, uruchamia JavaScript albo buduje DOM, ignoruje każdy z nich. Minifikacja to krok, który odrzuca materiał przeznaczony wyłącznie dla człowieka, gdy ludzie skończą już pracę nad źródłem. Dlatego właśnie minifikacja to sprawa produkcji, a nigdy fazy rozwoju: w repozytorium trzymasz wersję czytelną, a do przeglądarek wysyłasz wersję okrojoną. Czytelna kopia jest źródłem prawdy; kopia zminifikowana to artefakt budowania, który możesz odtworzyć w dowolnej chwili.

Jak działa minifikacja CSS

CSS minifikuje się najłagodniej z całej trójki, bo jego gramatyka zostawia mało miejsca na dwuznaczność. Minifikator usuwa komentarze, zwija ciągi białych znaków do zera, pomija ostatni średnik w każdym bloku i kasuje spacje wokół {, }, : oraz ;. Już to usuwa większość bajtów.

CSS dopuszcza też zestaw przekształceń równoważnych, których nie ma żaden inny język. Dobry minifikator stosuje je bezpiecznie:

  • Skrócenie kolorów. #ffffff staje się #fff, a #ff0000 zwija się do red (albo odwrotnie, zależnie od tego, co krócej zapisać).
  • Usunięcie jednostek przy zerze. 0px staje się 0, a margin: 0 0 0 0 staje się margin: 0.
  • Usunięcie zer wiodących. 0.5em staje się .5em.
  • Scalenie skrótów. Cztery osobne deklaracje margin-top, margin-right, margin-bottom i margin-left składają się w jedno margin.
  • Łączenie reguł. Sąsiednie reguły o identycznych selektorach lub deklaracjach można scalić, a zduplikowane deklaracje usunąć.

Każde z tych przekształceń zachowuje identyczny wyrenderowany rezultat, czyli granicę, której zgodny ze standardem minifikator nigdy nie przekracza. Ale CSS jest wrażliwy na kolejność: późniejsza reguła nadpisuje wcześniejszą przez kaskadę. Dlatego bezpieczny minifikator nie będzie na ślepo zmieniał kolejności reguł, jeśli mogłoby to zmienić, która deklaracja wygrywa. Zmniejszanie bajtów jest dozwolone, zmiana kaskady już nie.

To ograniczenie jest subtelniejsze, niż brzmi. Dwie deklaracje, które wyglądają na możliwe do scalenia, mogą nimi nie być, bo coś między nimi odwołuje się do tej samej właściwości o tej samej specyficzności. Rozważmy:

.btn { color: #ff0000; }
.alert .btn { color: blue; }
.btn { color: #f00; }

Pierwsza i trzecia reguła mają wspólny selektor i mogłyby się scalić, ale tylko jeśli nie przesunie to deklaracji za środkową regułę w sposób zmieniający, która wygrywa dla elementu pasującego do obu. Naiwne scalenie, które zmienia kolejność, mogłoby zepsuć kaskadę. To rodzaj przypadku brzegowego, o którym potrafi rozumować silnik klasy produkcyjnej jak CSSO, i dlatego nie warto sklecać własnego minifikatora typu „skasuj białe znaki” na wyrażeniach regularnych. Przekształcenia wyglądają mechanicznie, ale analiza bezpieczeństwa stojąca za nimi już nie.

Nasz minifikator CSS używa silnika CSSO właśnie do takiej bezstratnej minifikacji i działa w całości w przeglądarce, z odczytem zaoszczędzonych bajtów, dzięki któremu widać wpływ każdego przejścia na rozmiar ładunku. To samo narzędzie formatuje też w drugą stronę, więc możesz wziąć zminifikowany arkusz stylów skopiowany z działającej witryny i rozwinąć go z powrotem do czytelnych, wciętych reguł. Sięgnij po nie, gdy skopiujesz fragment CSS i chcesz sprawdzić jego skompresowany rozmiar, albo gdy wdrażasz statyczną stronę bez kroku budowania, który zrobiłby to za ciebie.

Jak działa minifikacja JavaScript

Minifikacja JavaScript idzie znacznie dalej niż CSS i tu właśnie kryją się zarówno oszczędności, jak i pułapki. Żeby zobaczyć dlaczego, spójrz na małą funkcję przed i po Terser:

// przed
function calculateTotal(items, taxRate) {
  let runningTotal = 0;
  for (const item of items) {
    runningTotal += item.price * item.quantity;
  }
  return runningTotal * (1 + taxRate);
}
// po
function calculateTotal(t,a){let n=0;for(const o of t)n+=o.price*o.quantity;return n*(1+a)}

Nazwa funkcji calculateTotal przetrwała, bo jest eksportowana (albo mogłaby zostać wywołana skądinąd); parametry i zmienne pętli zwijają się do pojedynczych liter. To sedno sprawy, ale minifikator JS robi kilka odrębnych rzeczy:

  • Manglowanie identyfikatorów. Zmienne lokalne i parametry zostają przemianowane na pojedyncze litery: getUserPreferences staje się a. Manglowane są tylko lokalne; globalne i eksportowane nazwy domyślnie pozostają nietknięte, bo ich przemianowanie zepsułoby kod, który odwołuje się do nich z zewnątrz.
  • Usuwanie martwego kodu. Nieosiągalne gałęzie i nieużywane zmienne są usuwane, działając ramię w ramię z tree-shakingiem na poziomie bundlera.
  • Zwijanie stałych i kompresja składni. Wyrażenia zostają skrócone: true staje się !0, false staje się !1, a return undefined; staje się return;.

Przy minifikacji JS najczęściej potyka się o pułapkę automatycznego wstawiania średników (ASI). JavaScript pozwala pomijać średniki, a parser wstawia je za ciebie według ściśle określonych reguł. Gdy minifikator usuwa podziały wierszy, od których te reguły zależą, kod może zmienić znaczenie. Klasyczna awaria to instrukcja zaczynająca się od ( lub [, którą po cichu sklei z poprzednim wierszem:

const x = getValue()
[1, 2, 3].forEach(handle)

Bez średników parsuje się to jako getValue()[1, 2, 3], czyli wyrażenie indeksujące, a nie dwie instrukcje. Po zminifikowaniu do jednej linii błąd zostaje zaszyty na stałe. To samo zagrożenie pojawia się przy wierszu zaczynającym się od (, gdzie poprzednie wyrażenie zostaje wywołane jak funkcja. Nowoczesny Terser radzi sobie z większością realnych przypadków łagodnie, bo najpierw parsuje kod do abstrakcyjnego drzewa składni i ponownie emituje średniki tam, gdzie są potrzebne, zamiast ślepo usuwać tekst. Ale złe źródło plus agresywna minifikacja to autentyczne źródło błędów produkcyjnych, a awarie są paskudne właśnie dlatego, że pojawiają się tylko w zminifikowanej kompilacji, nie podczas rozwoju. Naprawa leży po twojej stronie: pisz kod z jawnymi średnikami i jednoznaczną składnią, a minifikator pozostanie bezpieczny. Reguła lintera albo autoformatter wstawiający średniki na poziomie źródła całkowicie eliminuje ryzyko.

Zgodny ze standardem minifikator zachowuje zachowanie, ale tylko jeśli wejście to poprawny, standardowy JavaScript. Terser parsuje ECMAScript; nie rozumie TypeScriptu ani JSX. Te trzeba najpierw transpilować do zwykłego JS, inaczej minifikacja zawiedzie już na etapie parsowania. Jeśli wkleisz plik .ts do minifikatora JS i dostaniesz błąd, to właśnie dlatego.

Często wraca jedno pytanie o nazewnictwo: minify kontra uglify. Znaczą w praktyce to samo. „Uglify” pochodzi od UglifyJS, wczesnego popularnego minifikatora JS; Terser to jego nowoczesny fork wspierający ES2015 i nowsze. Dziś „minify” to ogólny termin dla wszystkich trzech języków, a „uglify” przetrwał jako starsza, swoista dla JS nazwa identycznego procesu.

Nasz minifikator JavaScript uruchamia Terser w przeglądarce: przemianowuje zmienne lokalne, usuwa martwy kod, wycina komentarze i raportuje, ile bajtów zaoszczędził w każdym przejściu.

Jak działa minifikacja HTML

Minifikacja HTML zaczyna się od podstaw: usunięcia komentarzy (z zachowaniem deklaracji <!DOCTYPE> i wszelkich komentarzy warunkowych, na których wciąż polegasz), zwinięcia białych znaków między znacznikami i przycięcia nadmiarowych spacji wewnątrz list atrybutów. Mały fragment pokazuje, jak to wygląda:

<!-- nav -->
<ul>
  <li><a href="/">Home</a></li>
  <li><a href="/about">About</a></li>
</ul>

staje się:

<ul><li><a href=/>Home</a><li><a href=/about>About</a></ul>

Komentarz zniknął, wcięcie między znacznikami zostało zwinięte, opcjonalne znaczniki zamykające </li> zostały pominięte, a niecytowane wartości atrybutów straciły cudzysłowy. Stąd minifikator może zastosować jeszcze kilka sztuczek właściwych dla HTML:

  • Usuwanie opcjonalnych znaczników zamykających. Specyfikacja HTML pozwala pominąć </li>, </p>, </td> i kilka innych, więc minifikator może je usunąć.
  • Usuwanie cudzysłowów z atrybutów. Gdy wartość nie ma spacji ani znaków specjalnych, class="x" staje się class=x.
  • Zwijanie atrybutów logicznych. disabled="disabled" staje się po prostu disabled, a checked="checked" staje się checked.
  • Minifikacja osadzonego CSS i JS. Zawartość bloków <style> i <script> również jest minifikowana, więc jedno przejście kurczy cały dokument.

Największe znaczenie ma tu jedna granica: w HTML białe znaki bywają znaczące. Wewnątrz <pre> i <textarea> każda spacja i nowy wiersz są renderowane dosłownie. Elementy z white-space: pre zachowują się tak samo. A białe znaki między elementami liniowymi wpływają na układ: spacja między dwoma znacznikami <a> pojawia się na stronie jako odstęp. Agresywna minifikacja, która spłaszcza te białe znaki, może zmienić wygląd strony. Reguła praktyczna: po minifikacji sprawdź renderowanie wokół pre, textarea i granic elementów liniowych, zanim wyślesz wersję na produkcję.

Nasz minifikator HTML formatuje przez js-beautify, a minifikuje przez CSSO i Terser dla osadzonych stylów i skryptów, w całości po stronie klienta. Przydaje się zwłaszcza przy HTML-u do e-maili i znacznikach eksportowanych z CMS, gdzie rzadko jest krok budowania, który skompresowałby je za ciebie.

Minify kontra gzip kontra Brotli: jak się nakładają

Jeśli serwer już udostępnia gzip albo Brotli, czy nadal trzeba minifikować? Tak, ponieważ obie techniki usuwają różną redundancję.

Minifikacja usuwa redundancję składniową na poziomie źródła: białe znaki, komentarze, długie nazwy i rozwlekłe konstrukcje, które istnieją dla czytelności dla człowieka. Gzip i Brotli usuwają statystyczną redundancję na poziomie bajtów: ciągi i wzorce powtarzające się w pliku zostają zastąpione krótszymi kodami. Jedno rozumie składnię twojego kodu; drugie widzi tylko strumień bajtów. Ponieważ celują w różne rzeczy, ich nakładanie działa dobrze.

Konkretny sposób, by to sobie wyobrazić: gzip świetnie zauważa, że ciąg function pojawia się w bundlu dwieście razy, i zastępuje każde wystąpienie krótkim odwołaniem wstecznym. Nie ma pojęcia, że getUserPreferences i getUserSettings to nazwy zmiennych, które mógłby skrócić, ani że cały blok if (false) { ... } nigdy się nie uruchomi. Minifikacja ogarnia dokładnie to: wygrane strukturalne i semantyczne, na które kompresor bajtowy jest ślepy. Uruchom je razem, a każde sprzątnie to, czego drugie nie widzi.

Liczby układają się w kolejności, w jakiej naprawdę się dzieje:

  1. Samo minify zwykle kurczy CSS, JS i HTML o 20–30%, usuwając białe znaki i komentarze oraz skracając składnię.
  2. Gzip na zminifikowanym wyjściu usuwa kolejne 60–80%, kodując powtarzające się wzorce, które pozostały w tekście.
  3. Brotli zamiast gzip daje wynik o 15–25% mniejszy ponownie, dzięki większemu wbudowanemu słownikowi i lepszemu algorytmowi.

Wniosek: najpierw minify, potem kompresja. Połączony rezultat jest często o 80–90% mniejszy od oryginalnego źródła. Te dwie operacje się nie wykluczają, a pominięcie którejkolwiek zostawia bajty na stole.

Dlaczego minifikacja nadal zarabia na siebie nawet ponad Brotli? Z trzech powodów:

  1. Mniejsze wejście kompresuje się mniej. Zminifikowany plik daje kompresorowi mniej redundantnego materiału do przeżucia, a mniejsze, czystsze wejście zwykle daje mniejsze wyjście.
  2. Minify robi rzeczy, których kompresja nie potrafi. Usuwanie martwego kodu i krótkie nazwy zmiennych to usunięcia semantyczne. Gzip nie rozumie twojego kodu, widzi tylko bajty, więc nigdy nie usunie nieużywanej funkcji ani nie przemianuje zmiennej.
  3. Przeglądarka parsuje mniej bajtów. Po dekompresji przeglądarka otrzymuje zminifikowany kod. Mniej kodu oznacza szybsze parsowanie i wykonanie, nie tylko mniejsze pobranie.

Kolejność nie jest kwestią wyboru; wynika z tego, gdzie żyje każdy krok. Minifikacja należy do czasu budowania (ty albo narzędzie budujące robicie ją raz). Kompresja należy do czasu transmisji (serwer robi ją na żądanie, przeglądarka dekompresuje po dotarciu). Potok jest więc naturalnie taki: minify → wdrożenie → serwer kompresuje. Nie da się go odwrócić: nie ma sposobu, by „skompresować, a potem zminifikować”, bo skompresowane wyjście nie jest już kodem źródłowym.

Jest mały, ale ważny wyjątek od zasady „najpierw minify, potem kompresja”: gdy treść jest już skompresowana, kompresowanie jej ponownie nie ma sensu albo wręcz szkodzi. Już binarne zasoby o wysokiej entropii (JPEG-i, PNG-i, WebP, czcionki w WOFF2) nic nie zyskują na gzip ani Brotli i nie powinny w ogóle trafiać do twoich reguł kompresji tekstu. Minifikacja to przekształcenie wyłącznie tekstowe, więc nigdy nie dotyka tych plików; to przy kompresji trzeba być wybiórczym. Skonfiguruj serwer tak, by kompresował tekstowe typy MIME (HTML, CSS, JS, JSON, SVG), a już skompresowane pliki binarne zostawiał w spokoju.

Konfiguracja warstwy transmisji (włączenie Brotli, ustawienie Content-Encoding) to sprawa operacyjna, którą zajmuje się serwer albo CDN. Ten przewodnik zostaje na warstwie źródła, gdzie odbywa się minifikacja. Jeśli optymalizujesz ładunek szerzej, to samo myślenie „oszczędzaj bajty na warstwie kodowania” stosuje się też do obrazów; nasz przewodnik po formatach obrazów omawia stronę WebP/AVIF/JPEG tej historii.

Kiedy nie trzeba minifikować ręcznie

Wiele reklam minifikatorów pomija jedno: jeśli masz krok budowania, twoje wyjście produkcyjne jest już zminifikowane. Nowoczesne potoki budowania robią to automatycznie.

Vite i esbuild minifikują JavaScript i CSS od ręki. Rollup i webpack robią to przez TerserPlugin i CssMinimizerPlugin. Lightning CSS obsługuje CSS z natywną szybkością. Next.js, Astro i podobne frameworki minifikują, robią tree-shaking i dzielą kod na fragmenty w swoich kompilacjach produkcyjnych bez kiwnięcia palcem z twojej strony. Polecenie to zwykle nic więcej niż vite build albo npm run build; minifikacja to część tego, co znaczy „zbuduj na produkcję”, a nie osobny krok, który się doczepia. Jeśli to opisuje twój projekt, przepuszczenie pliku przez osobny minifikator później jest w najlepszym razie zbędne, a w najgorszym szkodliwe: podwójne manglowanie już zminifikowanego kodu może dać mylące wyjście i nie zaoszczędzi sensownie dodatkowych bajtów.

Narzędzia budujące robią też coś, czego samodzielny minifikator nie potrafi: minifikują w kontekście całego grafu zależności. Tree-shaking w szczególności działa tylko wtedy, gdy bundler widzi każdy import i eksport oraz potrafi udowodnić, że dana funkcja nie jest nigdzie używana. Minifikator jednoplikowy nie ma grafu, o którym mógłby rozumować; może usunąć martwy kod wewnątrz podanego mu pliku, ale nie pozna, że cały zaimportowany moduł jest nieosiągalny. To kolejny powód, dla którego potok budowania jest właściwym domem dla minifikacji produkcyjnej.

Kiedy więc samodzielny minifikator jest właściwym narzędziem? W uczciwym zestawie przypadków, w których nie ma kroku budowania robiącego to za ciebie:

  • Statyczne witryny i ręcznie pisane jednoplikowe strony bez bundlera w obiegu.
  • Szablony HTML do e-maili, gdzie wiele systemów rozlicza za bajt i nie ma żadnego potoku budowania.
  • Fragmenty kodu i widgety od zewnętrznych dostawców, które osadzasz w cudzej stronie.
  • Szybkie sprawdzenie rozmiaru: wklej blok, zobacz, jak duży robi się po minifikacji i ile zaoszczędziłeś. Po to jest odczyt zaoszczędzonych bajtów.
  • Czytanie cudzego zminifikowanego kodu, gdzie uruchamiasz formatter w odwrotną stronę, by znów stał się czytelny.

Decyzja jest prosta. Masz build? Niech build minifikuje. Brak builda, jednorazowa potrzeba albo zwykłe sprawdzenie rozmiaru? Narzędzie online to najszybsza droga, a ponieważ działa w całości w przeglądarce, kod nigdy nie opuszcza twojego urządzenia. Ma to znaczenie dla kodu zastrzeżonego lub niewydanego, którego nigdy nie powinno się wklejać do formattera działającego po stronie serwera, który otrzymuje kopię wszystkiego. To ten sam argument o prywatności, który przewija się przez nasz przewodnik po stylu SQL, drugie głębokie ujęcie formatowania w tym klastrze.

Source mapy: debugowanie zminifikowanego kodu

Zminifikowany kod sam w sobie to koszmar przy debugowaniu. Gdy Terser przemianuje każdą zmienną lokalną na a, b i c, produkcyjny ślad stosu wskazujący na bundle.min.js:1:48211 nie mówi praktycznie nic o tym, co naprawdę się zepsuło.

Source mapy to rozwiązują. Source mapa to plik .map, który zapisuje odwzorowanie między każdą pozycją w zminifikowanym wyjściu a odpowiadającą jej pozycją w oryginalnym źródle. Gdy DevTools przeglądarki go wczyta, tłumaczy zminifikowane błędy z powrotem na prawdziwe nazwy plików, numery wierszy i nazwy zmiennych. Debugujesz wobec kodu, który napisałeś, mimo że przeglądarka uruchamia kod wyprodukowany przez twój build.

W praktyce narzędzie budujące generuje source mapę obok zminifikowanego bundla, a komentarz //# sourceMappingURL=bundle.min.js.map (lub nagłówek HTTP) wskazuje przeglądarce plik .map. Otwórz DevTools, natraf na błąd, a ślad stosu pokaże twoje prawdziwe nazwy plików i numery wierszy zamiast zminifikowanej zupy. Mapa jest wczytywana leniwie, tylko gdy DevTools jest otwarte, więc nic nie kosztuje twoich odwiedzających.

Warto znać pewien aspekt prywatności. Publiczna source mapa w praktyce wysyła twój oryginalny kod źródłowy każdemu, kto otworzy DevTools. Dla kodu otwartego to w porządku; dla kodu zastrzeżonego już nie. Po to są ukryte source mapy: bundle nie niesie komentarza sourceMappingURL, więc publika nigdy nie zobaczy mapy, a ty i tak przesyłasz ją do usługi monitorowania błędów, takiej jak Sentry. Usługa odwraca minifikację produkcyjnych śladów stosu po swojej stronie, dając ci czytelne błędy bez wystawiania źródła na świat.

To wzmacnia wcześniejszą myśl: source mapy to możliwość narzędzia budującego. Zwykły minifikator online zazwyczaj jej nie produkuje, bo jednorazowa kompresja jej nie potrzebuje. To kolejny powód, by minifikację produkcyjną powierzyć buildowi: daje ci mapę za darmo. Source mapa nigdy nie zmienia samego zminifikowanego bundla; to czysta pomoc w debugowaniu leżąca obok niego. Nie myl pliku .map z zależnością produkcyjną.

Najczęściej zadawane pytania

Czy minifikacja to to samo co kompresja?

Nie. Minifikacja przepisuje twój kod źródłowy, usuwając białe znaki i komentarze oraz skracając nazwy, tak że pozostaje poprawnym kodem, tylko mniejszym. Kompresja (gzip, Brotli) koduje powstałe bajty na potrzeby transmisji, a przeglądarka je dekoduje. Atakują różną redundancję, działają na różnych etapach i nakładają się: najpierw minify, potem kompresja.

Czy muszę minifikować, jeśli używam gzip lub Brotli?

Tak. Minifikacja nadal ma znaczenie przy gzip i Brotli. Zminifikowany kod daje kompresorowi mniej redundantnego wejścia, więc kompresuje się mniejszy, a minify wykonuje usunięcia semantyczne (martwy kod, krótkie nazwy zmiennych), których kompresja bajtowa nie potrafi. Przeglądarka też parsuje mniej bajtów. Używaj obu, w tej kolejności.

Czy minifikacja psuje mój kod?

Zgodny ze standardem minifikator zachowuje zachowanie: CSS renderuje się identycznie, a Terser utrzymuje JavaScript równoważnym. Wyjście działa tak samo jak źródło. Dwa zastrzeżenia: JavaScript polegający na automatycznym wstawianiu średników wymaga poprawnej składni, a wrażliwy na białe znaki HTML, jak <pre> czy <textarea>, należy zweryfikować po minifikacji.

Czym różni się minify od uglify?

Dla JavaScriptu znaczą w praktyce to samo. „Uglify” pochodzi od UglifyJS, wczesnego popularnego minifikatora JS; Terser to jego nowoczesny fork wspierający bieżącą składnię. Dziś mówi się „minify” ogólnie w odniesieniu do CSS, JS i HTML, a „uglify” to starsza, swoista dla JS nazwa tego samego procesu.

Czy powinienem minifikować podczas rozwoju?

Nie. Minifikuj kompilacje produkcyjne, nie wersję deweloperską. Zminifikowany kod jest nieczytelny i trudny do debugowania, więc podczas rozwoju chcesz mieć pełne, sformatowane źródło. Narzędzie budujące (Vite, esbuild, webpack) minifikuje automatycznie, gdy budujesz na produkcję, często z source mapami, byś nadal mógł debugować wdrożony bundle.

O ile minifikacja zmniejsza rozmiar pliku?

Samo minify zwykle kurczy CSS, JS i HTML o około 20–30%, głównie przez usunięcie białych znaków i komentarzy oraz skrócenie nazw. W połączeniu z gzip lub Brotli na wierzchu połączony rezultat jest często o 80–90% mniejszy od oryginalnego źródła. Dokładna liczba zależy od tego, ile białych znaków i redundancji miał plik.

Tagi: minification css javascript html web-performance build-tools code-optimization

Powiązane artykuły

Zobacz wszystkie artykuły