Jak włączyć kompresję Gzip

dowiedz się

Przyspieszenie ładowania witryny zaczyna się od zmniejszenia liczby bajtów wysyłanych do przeglądarki. Najprostszym krokiem jest włączenie Gzip, czyli bezstratnej kompresja transferu HTTP. W tym praktycznym przewodniku przeprowadzę Cię przez konfigurację na różnych platformach, pokażę testy, typowe błędy i bezpieczne ustawienia. Zadbamy też o prawidłowe nagłówki, współpracę z cache i to, by Twój serwer zyskał realną wydajność bez efektów ubocznych. Omówimy Apache, .htaccess, Nginx oraz alternatywy jak Brotli.

Jak działa Gzip i kiedy go używać

Co faktycznie kompresujemy

Gzip zmniejsza rozmiar treści tekstowych przed wysłaniem do przeglądarki. W praktyce największe zyski widać na plikach HTML, CSS, JavaScript, JSON, SVG, XML i czystym tekście. Kompresja działa w locie (dynamicznie) lub na gotowych, wcześniej spakowanych plikach (statycznie). Po stronie klienta przeglądarka informuje o obsługiwanych algorytmach w nagłówku Accept-Encoding, a serwer wybiera najlepszy wariant i odsyła Content-Encoding: gzip.

Co kompresować, a czego nie

  • Kompresuj: text/html, text/css, application/javascript, application/json, image/svg+xml, application/xml, text/plain, font/woff2 (zwykle już skompresowany – niektóre serwery i tak go nie dotykają).
  • Nie kompresuj: JPEG, PNG, WebP, AVIF, MP4, PDF, WOFF2 – te formaty mają już własną, skuteczną kompresję; dodatkowe gzipowanie tylko doda narzut CPU i nie zmniejszy plików.
  • Ostrożnie kompresuj odpowiedzi bardzo małe (poniżej ~1 kB) – narzut nagłówków i inicjalizacji potrafi zjeść korzyści.

Gzip a Brotli

Brotli bywa skuteczniejszy (mniejsze pliki) i jest szeroko wspierany, lecz jego kompresja bywa cięższa CPU-owo. W praktyce stosuje się strategię: Brotli dla HTTPS i nowoczesnych przeglądarek, Gzip jako bezpieczny fallback. Jeśli nie możesz wdrożyć Brotli, samo Gzip zapewnia duży zysk i bardzo dobrą kompatybilność.

Wymagania wstępne

  • Dostęp do konfiguracji serwera www lub przynajmniej możliwość edycji pliku .htaccess na hostingu współdzielonym.
  • Możliwość przeładowania/ponownego uruchomienia usługi (service reload, panel hostingowy lub SSH).
  • Dostęp do narzędzi testowych: curl, przeglądarka z DevTools, ewentualnie Lighthouse.

Włączanie Gzip na Apache

Sprawdź moduł mod_deflate i mod_filter

  • Na serwerze z SSH: a2enmod deflate filter, a potem przeładuj usługę: systemctl reload apache2 (Debian/Ubuntu) lub odpowiednik dla Twojej dystrybucji.
  • Jeśli nie masz dostępu do globalnej konfiguracji, skorzystasz z pliku .htaccess — pamiętaj, że hosting musi zezwalać na AllowOverride.

Konfiguracja globalna (apache2.conf lub vhost)

Wstaw do sekcji serwera (np. w pliku vhost):

  • AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json application/xml image/svg+xml
  • DeflateCompressionLevel 6
  • BrowserMatch ^Mozilla/4 gzip-only-text/html
  • Header append Vary Accept-Encoding
  • Header set Content-Encoding gzip env=compressible

Uwaga: niektóre dystrybucje używają modułu headers do ustawiania nagłówków. Upewnij się, że jest aktywny (a2enmod headers). DeflateCompressionLevel pozwala zmienić balans CPU/rozmiar (4–7 to rozsądny kompromis).

Konfiguracja w .htaccess (hostingi współdzielone)

Dodaj do .htaccess w katalogu głównym witryny:

  • IfModule mod_deflate.c
  • AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json application/xml image/svg+xml
  • DeflateCompressionLevel 6
  • SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png|webp|avif|mp4|pdf|woff2)$ no-gzip dont-vary
  • Header append Vary Accept-Encoding env=!dont-vary
  • /IfModule

Składnię IfModule/IfModule domknij odpowiednimi nawiasami (ukośniki wskazują miejsce zamknięcia w przykładzie). Reguła SetEnvIfNoCase pozwala wykluczyć typy, których nie chcesz kompresować.

Wykluczenia i ochrona przed podwójną kompresją

  • Jeśli aplikacja sama kompresuje odpowiedzi (np. PHP z zlib.output_compression), nie włączaj tego równocześnie w serwerze — grozi uszkodzeniem danych lub błędami w kliencie.
  • Nie kompresuj odpowiedzi już podpisanych Content-Encoding. W Apache można warunkować Header set Content-Encoding gzip env=compressible tak, by ustawiać go tylko dla wskazanych typów.

Cache i nagłówek Vary

Koniecznie ustaw Vary: Accept-Encoding. Dzięki temu cache pośrednie (CDN, proxy) przechowują osobne kopie skompresowaną i nieskompresowaną. Przykład w .htaccess: Header append Vary Accept-Encoding.

Test i przeładowanie

  • Przeładuj Apache: systemctl reload apache2 lub apachectl graceful.
  • Sprawdź curl: curl -I -H „Accept-Encoding: gzip” https://twojadomena.pl/ i upewnij się, że widzisz Content-Encoding: gzip oraz Vary: Accept-Encoding.

Włączanie Gzip na Nginx

Podstawowe włączenie w bloku http

Edytuj /etc/nginx/nginx.conf lub plik w /etc/nginx/conf.d/ i w sekcji http dodaj:

  • gzip on;
  • gzip_comp_level 5;
  • gzip_min_length 1024;
  • gzip_proxied any;
  • gzip_vary on;
  • gzip_types text/plain text/css application/javascript application/json application/xml image/svg+xml;

gzip_comp_level 4–6 zapewnia dobry kompromis. gzip_min_length chroni przed kompresją bardzo małych odpowiedzi. gzip_vary dodaje Vary: Accept-Encoding.

Kompresja dynamiczna i statyczna

  • Dynamiczna: jak wyżej — Nginx kompresuje odpowiedź w locie.
  • Statyczna: jeśli utrzymujesz zasoby w wersjach .gz, włącz gzip_static on; i serwuj pliki prekompresowane (np. style.css.gz). To zdejmuje obciążenie CPU z serwera i bywa korzystne przy dużym ruchu.
  • Automatyczne budowanie .gz: zorganizuj pipeline (np. npm scripts, Gulp, Webpack) generujący .gz w czasie deployu.

HTTP/2, TLS i bezpieczeństwo

Kompresuj tak samo dla HTTP/2; mechanizmy HPACK/H2 nie zastępują kompresji treści. Unikaj kompresji odpowiedzi wrażliwych z danymi tajnymi, zwłaszcza gdy treść zawiera elementy kontrolowane przez użytkownika i jest łączona z danymi poufnymi (ryzyko wektorów jak BREACH). Rozważ wyłączenie kompresji dla ścieżek z tokenami CSRF lub parametrami tajnymi.

Przeładowanie i walidacja

  • Sprawdź składnię: nginx -t.
  • Przeładuj: systemctl reload nginx.
  • Test: curl -I -H „Accept-Encoding: gzip” https://twojadomena.pl/ i upewnij się, że widzisz Content-Encoding: gzip i Vary: Accept-Encoding.

IIS, PHP, Node.js i rozwiązania CDN

IIS: włączanie kompresji w Managerze

  • Otwórz IIS Manager → Compression.
  • Włącz Enable dynamic content compression oraz Enable static content compression.
  • W razie potrzeby dodaj/zmodyfikuj typy MIME w applicationHost.config (section system.webServer/httpCompression i urlCompression).
  • Recykl aplikacji lub iisreset, następnie testuj nagłówki.

PHP: zlib.output_compression lub ob_gzhandler

  • php.ini: zlib.output_compression=On oraz zlib.output_compression_level=5–6. Zrestartuj FPM/Apache.
  • Lub w kodzie: ob_start(’ob_gzhandler’); przed wysłaniem danych. Pamiętaj, by nie dublować z kompresją w serwerze www.
  • Jeśli używasz frameworków, sprawdź czy nie mają własnej warstwy kompresji middleware.

Node.js: middleware compression

  • Dodaj pakiet: npm i compression.
  • W aplikacji Express: const compression = require(’compression’); app.use(compression({ level: 6, threshold: '1kb’ }));
  • Wyklucz już skompresowane typy (np. obrazy), ustaw Vary: Accept-Encoding. W przypadku SSR zwróć uwagę na fragmenty wrażliwe na BREACH.

CDN i reverse proxy (Cloudflare, CloudFront, Fastly)

  • Cloudflare: włącz Auto Minify i Brotli/Gzip w sekcji Speed → Optimization. Dla starszych klientów CDN dostarczy Gzip, dla nowoczesnych Brotli.
  • Amazon CloudFront: w atrybutach Behavior → Compress objects automatically ustaw On, dodaj typy MIME.
  • Fastly/akamai: w politykach włącz kompresję i potwierdź dodanie Vary: Accept-Encoding.
  • Upewnij się, że origin nie podwaja kompresji; często najlepiej pozwolić CDN-owi kompresować na krawędzi, a origin serwować bez Content-Encoding.

WordPress i inne CMS

  • Jeśli nie masz dostępu do serwera, użyj wtyczek optimize/performace (np. włączających kompresję i dodających nagłówek Vary).
  • Na hostingach współdzielonych kompresję często włącza panel. Sprawdź dokumentację dostawcy.
  • Niektóre wtyczki minifikujące mają własną opcję Gzip — nie duplikuj z konfiguracją serwera.

Weryfikacja i rozwiązywanie problemów

Szybkie testy w terminalu

  • curl -I -H „Accept-Encoding: gzip” https://twojadomena.pl/ — sprawdź Content-Encoding: gzip i Vary: Accept-Encoding.
  • curl -s -H „Accept-Encoding: gzip” https://twojadomena.pl/ | wc -c vs. curl -s https://twojadomena.pl/ | wc -c — porównaj rozmiary strumienia.
  • Jeśli serwujesz gzip_static, spróbuj pobrać konkretny zasób CSS/JS i zobacz, czy rozmiar maleje.

DevTools i Lighthouse

  • W Chrome → DevTools → Network → wybierz zasób → zakładka Headers: sprawdź Content-Encoding i size (zobacz transferred vs resource size).
  • Lighthouse/Pagespeed: reguła Enable text compression pokaże, które zasoby nie są kompresowane i ile możesz zyskać.

Typowe konflikty i ich naprawa

  • Podwójna kompresja: usuń nakładające się warstwy (np. PHP zlib i Nginx jednocześnie). Ustal, gdzie kompresujesz: aplikacja, serwer, czy CDN.
  • Błędne typy MIME: jeśli Content-Type jest application/octet-stream, reguły oparte na typach mogą nie zadziałać. Ustaw właściwe typy MIME.
  • Proxies i stare przeglądarki: w razie problemów pozostaw Vary: Accept-Encoding i nie wymuszaj kompresji na user-agentach, które jej nie obsługują.
  • Uszkodzone odpowiedzi: sprawdź, czy żaden filtr nie modyfikuje Content-Length po kompresji; najlepiej go nie ustawiać ręcznie przy dynamicznych odpowiedziach.

Bezpieczeństwo: kiedy rozważyć wyłączenie

  • BREACH/CRIME: jeśli odpowiedź łączy dane tajne (np. tokeny) z danymi kontrolowanymi przez użytkownika i jest kompresowana, rozważ wyłączenie kompresji dla takich endpointów lub wstrzykiwanie losowego paddowania.
  • API z danymi poufnymi: zostaw Gzip, ale ogranicz do application/json bez pól z tajnymi tokenami w odpowiedzi, lub wyłącz dla specyficznych tras.

Monitorowanie i metryki

  • Zbieraj rozmiary transferu i CPU na warstwie serwera/CDN. Upewnij się, że poziom kompresji nie przeciąża procesora w godzinach szczytu.
  • Sprawdzaj procent hitów cache. Przy prawidłowym Vary: Accept-Encoding nie powinno dochodzić do błędnych trafień.

Najlepsze praktyki wdrożeniowe

Lista kontrolna

  • Włącz kompresję dla typów tekstowych; wyklucz formaty już skompresowane (JPEG/PNG/WebP/AVIF/WOFF2/MP4/PDF).
  • Ustaw Vary: Accept-Encoding i poprawne Content-Type dla każdego zasobu.
  • Zadbaj o minimalny rozmiar (Nginx: gzip_min_length, Apache: rozważ reguły warunkowe) oraz rozsądny poziom (5–6).
  • Sprawdź brak podwójnej kompresji na styku aplikacja–serwer–CDN.
  • Rozważ gzip_static lub prekompresję w pipeline, jeśli masz wysokie RPS i ciężkie pliki JS/CSS.
  • Przetestuj w curl i DevTools, a następnie w Lighthouse.

Dobór Gzip vs Brotli

  • Jeśli możesz, włącz oba: Brotli dla HTTPS/nowoczesnych klientów, Gzip jako fallback.
  • Dla serwerów o słabszym CPU trzymaj umiarkowane poziomy kompresji; ciężkie poziomy Brotli (9–11) stosuj tylko przy prekompresji statycznej.

Integracja z pipeline i CI/CD

  • Buduj .gz (i .br) dla plików statycznych podczas deployu; publikuj obok oryginałów i ustaw serwer/CDN do serwowania właściwego wariantu.
  • Automatyczne testy: skrypt CI może wywołać curl i sprawdzić Content-Encoding dla kilku kluczowych zasobów.

Specjalne przypadki i kompatybilność

  • Aplikacje SPA: duży bundle JS przynosi największe zyski z kompresji; rozważ dzielenie kodu i prekompresję.
  • Serwowanie fontów: WOFF2 jest skompresowany; unikaj dodatkowego Gzip, ale zostaw nagłówek Vary.
  • Edge computing/Workers: kompresuj na krawędzi, a origin zostaw odciążony.

Szybkie instrukcje do skopiowania

  • Apache (.htaccess): AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json image/svg+xml; Header append Vary Accept-Encoding; DeflateCompressionLevel 6.
  • Nginx (http): gzip on; gzip_types text/html text/css application/javascript application/json image/svg+xml; gzip_comp_level 5; gzip_min_length 1024; gzip_vary on.
  • Node (Express): app.use(require(’compression’)({ level: 6, threshold: '1kb’ }));
  • PHP (php.ini): zlib.output_compression=On; zlib.output_compression_level=6.
< Powrót

Zapisz się do newslettera


Zadzwoń Napisz