Kompresja danych w serwerach WWW na przykładzie Nginx
Czym jest kompresja zapewne każdy wie, ale dlaczego uruchamia się kompresję na serwerach WWW typu Apache lub Nginx? Kompresja to nic innego jak bezstratny zapis danych w sposób który pozwala na wykorzystanie mniejszej ilości bitów. Popularne serwer WWW umożliwiają uruchomienie kompresji danych dla statycznych zasobów. Taki zabieg może znacznie przyspieszyć renderowanie się stron i zmniejszyć ilość przesyłanych danych przez sieć.
Kiedy warto uruchomić kompresję, a kiedy lepiej ją pominąć?
Optymalizacja statycznych zasobów zwracanych z serwera może znacznie przyspieszyć renderowanie treści o ile nie jest to system zamknięty do zasobów lokalnych. W niektórych przypadkach kompresja może okazać się zbędna a nawet spowolnić aplikację. Takim przypadkiem może być zamknięty system do zasobów sieci lokalnej w której transfer danych jest względnie szybki.
Kompresja może znacznie zmniejszyć ilość przesyłanych danych pomiędzy serwerem a klientem, dlatego warto uruchomić tę funkcję serwera w przypadku aplikacji dostępnej w sieci WEB. W tym przypadku nie mamy pewności, czy odbiorca ma szybkie łącze.
O czym warto pamiętać?
Kompresja danych może przyspieszyć przesyłanie danych przez sieć a co za tym idzie, druga strona będzie musiała wykonać operację odwrotną do kompresji jaką jest dekompresja. Warto tu wspomnieć, że proces dekompresji to dodatkowe obciążenie procesora po stronie klienta.
Warto również wiedzieć, że uruchamianie kompresji dla plików graficznych typu JPEG, PNG, GIF oraz innych plików binarnych może okazać się znikomą optymalizacją. Te typy plików są często wstępnie skompresowane i ponowna ich kompresja spowoduje nawet pogorszenie wyniku pod względem optymalizacyjnym.
Jak sprawdzić, czy na serwerze jest włączona kompresja?
W internecie zapewne znajdziesz wiele narzędzi online które sprawdzą czy na badanej przez Ciebie stronie uruchomiona jest kompresja, warto jednak wiedzieć co faktycznie te narzędzia sprawdzają. To bardzo proste, kiedy serwer uruchamia kompresję musi poinformować klienta, że jest ona uruchomiona i robi to za pomocą specjalnego nagłówka content-encoding
:
Format kompresji... który wybrać?
Dużego wyboru nie ma, aktualnie najpopularniejszymi algorytmami kompresji danych pobieranych z serwera WWW jest Defalte, Gzip i Brotli.
Deflate to połączenie algorytmów LZ77 i kodowania Huffmana, jest to podstawowy format kompresji wykorzystywany w Gzip
Gzip to najpopularniejszy format kompresji, który wykorzystuje wyżej opisany Deflate. Jest wspierany przez wszystkie możliwe przeglądarki internetowe.
Brotli to połączenie algorytmów LZ77, kodowania Huffmana i modelowania kontekstowego drugiego rzędu bardzo dobrze opisany przez RFC-932 gdyby ktoś był bardziej zainteresowanych. Na dzień dzisiejszy nie każda przeglądarka wspiera kompresję BR
Pomimo tego, że Brotli jeszcze nie jest wspierany w każdej przeglądarce internetowej warto jest uruchomić ten format. Przeglądarki, które wspierają Brotli wysyłają odpowiedni nagłówek do serwera, dzięki czemu nic nie stoi na przeszkodzie żeby umożliwić zwracanie statycznych zasobów w wybranym przez klienta formacie.
Brotli jest wydajniejszy niż Gzip, w przypadku plików JS i CSS oraz innych plików tekstowych optymalizacja może być wyższa od 15 do nawet 20 procent.
Poziom kompresji - nie warto z nią przesadzać
W przypadku jakiejkolwiek kompresji po stronie serwera możemy ustalić jej poziom, czyli intensywność wykorzystywanych algorytmów. Niestety zbyt wysoki poziom kompresji na serwerze może niekorzystnie wpłynąć na zużycie procesora.
Wysoki poziom kompresji wymaga wykonania więcej obliczeń przez co serwer może być przez ten proces zbyt obciążony. Należy dobrać optymalny poziom kompresji w ten sposób, żeby nie był to problem dla naszego serwera przy zwiększonym ruchu i jednoczesnym zachowaniu zadowalającego rozmiaru zwracanych zasobów.
Jest to kwestia indywidualna, która zależy od wielu czynników. Na początku warto ustawić poziom kompresji w przypadku Gzip na wartość 6 i monitorować zachowanie maszyny.
Kompresja statyczna = lepsza wydajność
Możemy zlecić kompresję aplikacji serwerowej lub dostarczyć skompresowane zasoby na serwer.
Jest to bardzo dobra alternatywa dla aplikacji, które zbyt dotkliwie obciążają serwer WWW. Tworząc aplikacje klienckie przy pomocy popularnych frameworków tj. Angular, Vue.js, React.js, Knockout.js warto zastanowić się nad wdrożeniem kilku dodatkowych mechanizmów do WebPack, które zadbają o to, żeby wynikowa aplikacja była już skompresowana.
Podsumowując - statyczna kompresja może poprawić wydajność poprawiając przy tym poziom skompresowania danych.
Uruchamianie kompresji Gzip i Brotli w serwerze Nginx
To jak prawidłowo uruchomić kompresję zasobów statycznych w serwerze WWW Nginx najlepiej oczywiście opisuje dokumentacja do której też odsyłam. Żeby ten wpis jednak był bardziej wartościowy muszę tu podać gotowe przykłady konfiguracji, które stosuję na maszynach którymi zarządzam :) - zaczynamy
gzip on;
gzip_disable "msie6";
gzip_comp_level 7;
gzip_min_length 1000;
gzip_vary on;
gzip_proxied any;
gzip_buffers 16 8k;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/atom+xml;
Powyższa konfiguracja uruchamia kompresję, wyłącza kompresję dla przeglądarki IE w wersji 6, ustawia poziom kompresji na poziom 7, nie uruchamia kompresji plików które są mniejsze niż 1000 bajtów oraz pozwala na kompresję również klientom podłączonych przez Proxy. Parametr gzip_buffers
określa ilość buforów jak i ich wielkość(domyślnie jest to jedna strona pamięci której wielkość zależy od platformy). W powyższym przykładzie rozszerzyłem również typy plików które mają być poddawane operacji kompresji do plików tekstowych, JSON, JavaScript i XML.
Uruchamianie kompresji Brotli
Moduł nginx_brotli
nie jest domyślnie zainstalowany, dlatego przed przystąpieniem do konfiguracji musimy go zainstalować na maszynie:
Najczęściej pracuję na Ubuntu, dlatego posługuję się apt
, jeżeli masz inny system
apt-get install nginx-plus-module-brotli
na samej górze pliku nginx.conf
ładujemy nowy moduł:
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
Teraz możemy przystąpić do konfiguracji Brotli, wszystkie możliwe dyrektywy to:
- brotli_static
- brotli
- brotli_types
- brotli_buffers
- brotli_comp_level
- brotli_window
- brotli_min_length
Konfiguracja Brotli jest analogiczna do konfiguracji Gzip:
brotli on;
brotli_comp_level 7;
brotli_min_length 1000;
brotli_buffers 16 8k;
brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/atom+xml;
Podsumowanie
Jeżeli chcesz przyspieszyć renderowanie aplikacji i zoptymalizować ilość przesyłanych danych przez sieć, co ma istotne znaczenie kiedy dostawca serwera ma restrykcyjne limity transferu(lub transfer jest drogi - cloud computing) warto zastanowić się nad uruchomieniem kompresji danych na swoim serwerze w celu optymalizacji.