Dokumentacja
Włącz Brotli lub gzip
Włącz Brotli lub gzip
HTML, CSS i JavaScript to zwykły tekst, a tekst kompresuje się bardzo dobrze: skrypt o rozmiarze 300 KB z gzipem zwykle przesyłany jest jako 70–90 KB, z Brotli jeszcze trochę mniej. Przeglądarka rozpakowuje go w ułamku milisekundy. Bez kompresji każdy odwiedzający pobiera trzy do pięciu razy więcej, niż potrzeba, co najbardziej odczuwa się na telefonie ze słabym zasięgiem, a strona traci w pomiarach szybkości Google.
Kompresja to ustawienie serwera, a nie coś, co robi kod strony. Lista kontrolna strony sprawdza ją w dwóch miejscach: na samej stronie oraz na plikach CSS i JavaScript, które strona ładuje z Twojej domeny.
Co powinno być skompresowane
| Kompresuj | Nie kompresuj |
|---|---|
HTML (text/html) |
JPEG, PNG, WebP, AVIF, GIF |
CSS (text/css) |
czcionki WOFF2 |
JavaScript (application/javascript, text/javascript) |
wideo, audio, ZIP, PDF |
| JSON, XML, SVG, zwykły tekst |
Prawa kolumna jest już skompresowana; ponowna kompresja tylko zużywa procesor. Brotli (br) daje trochę mniejsze pliki niż gzip i obsługują go wszystkie obecne przeglądarki, ale do listy kontrolnej wystarczy sam gzip.
Najczęstszą przyczyną żółtej pozycji "CSS and JavaScript compressed" jest nginx: Debian i Ubuntu instalują go z gzip on, ale linia wymieniająca pozostałe typy plików jest zakomentowana, więc kompresowany jest tylko HTML.
Sprawdź sam
Zamiast example.com wpisz swoją stronę, a zamiast drugiego adresu jeden ze swoich plików CSS lub JS (lista kontrolna wymienia te, które znalazła nieskompresowane):
curl -s -o /dev/null -D - -H 'Accept-Encoding: br, gzip' https://example.com/ | grep -i '^content-encoding'
curl -s -o /dev/null -D - -H 'Accept-Encoding: br, gzip' https://example.com/assets/app.css | grep -i '^content-encoding'
content-encoding: br albo content-encoding: gzip oznacza kompresję. Brak wyniku oznacza, że plik został wysłany bez zmian.
Jak to naprawić
Wybierz miejsce, które faktycznie wysyła pliki. Jeśli przed stroną stoi Cloudflare, to on kompresuje; w przeciwnym razie jest to serwer WWW albo panel hostingu.
nginx
Otwórz /etc/nginx/nginx.conf (ta sama ścieżka na Debianie, Ubuntu, Rocky, Alma i CentOS) i w bloku http { … } upewnij się, że linie gzip są aktywne, a nie zakomentowane:
http {
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/css text/plain text/xml application/javascript text/javascript
application/json application/xml application/rss+xml image/svg+xml;
}
text/html jest kompresowany zawsze, gdy ustawiono gzip on, więc nie ma go na liście. gzip_vary mówi cache'om, że odpowiedź zależy od tego, co akceptuje przeglądarka, a gzip_proxied any utrzymuje kompresję, gdy żądanie przychodzi przez CDN albo inny proxy.
Brotli wymaga osobnego modułu ngx_brotli. Tam, gdzie dystrybucja ma go w pakiecie (w nowszych Debianie i Ubuntu jako libnginx-mod-http-brotli-filter), zainstaluj go i dodaj obok linii gzip:
brotli on;
brotli_comp_level 5;
brotli_types text/css text/plain text/xml application/javascript text/javascript
application/json application/xml application/rss+xml image/svg+xml;
Sprawdź i zastosuj:
sudo nginx -t && sudo systemctl reload nginx
Apache i LiteSpeed
Z dostępem do serwera (Apache). Kompresja to mod_deflate. Na Debianie i Ubuntu włącz go przez sudo a2enmod deflate; na Rocky, Alma i CentOS jest ładowany domyślnie. Następnie dodaj do <VirtualHost> strony albo do .htaccess:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
AddOutputFilterByType DEFLATE application/javascript text/javascript
AddOutputFilterByType DEFLATE application/json application/xml application/rss+xml image/svg+xml
</IfModule>
sudo apachectl configtest && sudo systemctl reload apache2
(Na Rocky, Alma i CentOS httpd zamiast apache2.) Apache 2.4.26 i nowsze ma też mod_brotli (sudo a2enmod brotli) z filtrem BROTLI_COMPRESS dla tych samych typów.
Bez dostępu do serwera (hosting współdzielony). Wstaw ten sam blok do .htaccess w głównym folderze strony. Serwery LiteSpeed kompresują na poziomie serwera, zwykle z już włączonymi gzip i Brotli; jeśli na hostingu z LiteSpeed sprawdzenie nadal nie pokazuje kompresji, poproś wsparcie o jej włączenie.
cPanel
- Otwórz Software → Optimize Website.
- Wybierz Compress All Content (albo Compress the specified MIME types i wpisz typy z tabeli powyżej).
- Kliknij Update Settings.
cPanel zapisuje reguły mod_deflate w .htaccess strony. Jeśli tego ekranu nie ma albo sprawdzenie nadal nie pokazuje kompresji, serwerem może być LiteSpeed lub nginx; zapytaj hosting, dla niego to ustawienie serwera.
Plesk
W Plesku nginx zwykle stoi przed Apache i to on wysyła pliki odwiedzającemu, więc tam należy kompresja. Websites & Domains → example.com → Apache & nginx Settings, w Additional nginx directives dodaj:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_types text/css text/plain text/xml application/javascript text/javascript
application/json application/xml image/svg+xml;
Kliknij OK; Plesk sprawdzi składnię i przeładuje nginx. Jeśli strona działa tylko na Apache (nginx wyłączony), użyj zamiast tego bloku .htaccess z zakładki Apache.
Cloudflare
Gdy strona działa za Cloudflare (pomarańczowa chmurka), Cloudflare kompresuje HTML, CSS, JavaScript i inne typy tekstowe przez Brotli lub gzip w drodze do odwiedzającego, na każdym planie, niezależnie od tego, co robi serwer. Nie trzeba niczego włączać.
Jeśli sprawdzenie nadal nie pokazuje kompresji, poszukaj jednej z tych rzeczy:
- Rekord jest DNS only (szara chmurka), więc ruch nie przechodzi przez Cloudflare.
- Serwer wysyła
Cache-Control: no-transform, co zabrania Cloudflare zmieniać odpowiedź. - Plik jest serwowany z innej domeny, która nie jest w Cloudflare.
WordPress
Sam WordPress niczego nie kompresuje; robi to serwer WWW. Wtyczki cache mogą pomóc w konfiguracji: WP Rocket zapisuje reguły mod_deflate w .htaccess, a W3 Total Cache ma opcję gzip w Performance → Browser Cache. Obie działają tylko na Apache lub LiteSpeed, gdzie .htaccess jest czytany. Na nginx te reguły nic nie robią.
Jeśli strona używa LiteSpeed Cache, kompresuje serwer LiteSpeed, a nie wtyczka. Jeśli po ustawieniu wtyczki i wyczyszczeniu cache pozycja nadal jest żółta, użyj zakładki dla swojego panelu hostingu lub serwera albo zapytaj hosting.
Node.js i Next.js
Next.js kompresuje odpowiedzi gzipem, gdy uruchamiasz go przez next start (compress: true to ustawienie domyślne). Jeśli przed nim kompresuje już nginx albo CDN, wyłącz to w next.config.js, aby praca nie była wykonywana dwa razy:
module.exports = {
compress: false,
};
Express potrzebuje middleware compression (npm install compression), zarejestrowanego przed trasami i plikami statycznymi:
const compression = require('compression');
app.use(compression());
Przy obciążonej stronie taniej jest zostawić kompresję nginx albo CDN, a Node zostawić aplikacji.
IIS i ASP.NET
IIS domyślnie kompresuje pliki statyczne (CSS, JS), ale kompresja stron dynamicznych to osobna funkcja roli. Zainstaluj Dynamic Content Compression w Server Manager (Add Roles and Features → Web Server → Performance), a potem włącz obie w web.config strony:
<configuration>
<system.webServer>
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
</system.webServer>
</configuration>
Dla Brotli Microsoft udostępnia darmowe rozszerzenie IIS Compression, które dodaje schemat Brotli obok gzip.
Platformy hostowane
Shopify, Wix, Squarespace i Webflow kompresują wszystko same. Jeśli lista kontrolna zgłasza tam nieskompresowany plik, zwykle pochodzi on z aplikacji zewnętrznej albo z zewnętrznego hostingu, który możesz zapytać, a nie z platformy.
Na co uważać
- Kopie w cache. CDN albo wtyczka cache może dalej serwować kopię zapisaną przed zmianą. Po włączeniu kompresji wyczyść cache.
- Podwójna kompresja.
zlib.output_compressionw PHP i serwer WWW nie powinny kompresować jednocześnie: to marnuje procesor, a w niektórych konfiguracjach przeglądarka dostaje odpowiedź, której nie umie odczytać. Niech robi to serwer WWW. - Pliki skompresowane wcześniej. Narzędzia do budowania mogą tworzyć
app.css.gziapp.css.brobok oryginału. nginx serwuje je przezgzip_static on;(a z modułembrotli_static on;), co oszczędza procesor przy każdym żądaniu.
Potwierdź poprawkę
Uruchom ponownie oba polecenia curl z sekcji Sprawdź sam, następnie otwórz cel w PulseKeeper i kliknij Sprawdź teraz na zakładce Lista kontrolna. Obie pozycje, dla strony oraz dla CSS i JavaScript, zmienią się na OK w ciągu kilku minut, a nie dopiero przy następnym codziennym sprawdzeniu.