Lepsze wyniki w PageSpeed Insights za pomocą optymalizacji pliku .htaccess

| czas czytania: 5 min | SEO
prędkość ładowania strony

Google PageSpeed Insights to jedno z narzędzi z pakietu Google PageSpeed Tools, które służy użytkownikom do oceny i poprawy optymalizacji, wydajności oraz szybkości wczytywania stron internetowych. Rodzina narzędzi nosi nadrzędną nazwę Google PageSpeed i zawiera w sobie szereg komponentów: Service, Chrome DevTools, Module i opisywany tutaj Insights.

Aktualizacja narzędzia i Speed Update

10 stycznia 2018 roku Google na swoim oficjalnym blogu poinformowało o aktualizacji narzędzia Google PageSpeed Insights. Wcześniejsza wersja po przeprowadzeniu testu dowolnej strony prezentowała jeden wskaźnik w skali 0/100. Wynik zależny był od ilości i jakości optymalizacji wprowadzonych w badanym serwisie. Poza oceną czasu ładowania strony pojawiała się lista wskazówek optymalizacyjnych.

Problemem w PageSpeed Insights była kwestia oderwania wyniku od rzeczywistości. Podana wartość nie wskazywała jak szybko tak naprawdę działa badana strona. W styczniu Google wyszło naprzeciw oczekiwaniom użytkowników i zaczęło przygotowywać grunt pod zapowiedziany tydzień później Speed Update. Nowa wersja narzędzia do optymalizacji czasu ładowania strony została rozbudowana o dodatkowe informacje.

Aktualizacja Page Speed

Jeden wynik został rozbity na dwie kategorie główne i dodatkowe wskaźniki:

  • Optymalizacja – w skali od 0 do 100 i z oceną Good, Medium lub Low weryfikuje ilość oraz jakość wprowadzonych na stronie optymalizacji mających na celu poprawę wydajności.
  • Szybkość działania strony – z oceną Fast, Average i Slow weryfikuje realną szybkość działania strony wedle danych z Chrome User Experience Report. Na dzień dzisiejszy wiele witryn nie dysponuje jeszcze odpowiednią pulą danych i zamiast wyniku wyświetla się „Unavailable”.
Screen szybkość działania strony
  • FCP i DCL (First Contentful Paint, DOM Content Loaded) – od wyniku tych dwóch wartości zależy ogólna ocena szybkości strony. FCP i DCL oceniane są jako Fast, Average i Slow na podstawie porównania z innymi wynikami z bazy danych. Zakres podzielony jest na 3 zbiory, najszybsza 1/3 to wynik Fast.
Rozkład wczytywania strony www

17 stycznia 2018 roku Google zapowiedziało tzw. Speed Update, który wejść w życie ma w lipcu 2018. Nowy algorytm obejmie mobilną wyszukiwarkę. Zgodnie z oświadczeniem po wprowadzeniu aktualizacji w wynikach organicznych dla urządzeń mobilnych gorsze pozycje może odnotować grupa najwolniejszych i najgorzej zoptymalizowanych witryn. Webmasterzy mają zatem czas do wakacji, aby poprawić page speed swoich serwisów. Jednym z podstawowych i najprostszych sposobów na poprawę wydajności jest skorzystanie z optymalizacji, które można wprowadzić do pliku .HTACCESS.

Optymalizacje w .HTACCESS

Poniższe optymalizacje wprowadzać można bezpośrednio do pliku .htaccess. Jest to plik znajdujący się zazwyczaj na serwerze w katalogu głównym witryny. Istotne, aby sprawdzić, czy wspomnianych modułów automatycznie nie wprowadza CMS lub inna aplikacja. Przykładowo WordPress posiada wtyczkę, która sama wdraża do kodu Cache-Control headers. Należy unikać sytuacji, gdy CMS generuje te moduły samodzielne i wprowadzenie ich ręcznie do .htaccess spowoduje ich duplikację.

Cache-control headers i Expire headers – wykorzystanie pamięci podręcznej

Wprowadzenie Cache-Control headers lub Expire headers jest jedną z odpowiedzi na sugerowane przez PageSpeed optymalizacje dotyczące wykorzystania pamięci podręcznej przeglądarki.

Cache-control vs Expire – zastosowanie i różnice

Podstawową kwestią jest czas ich powstania – Expire Headers zostały wprowadzone w HTTP 1.0, a Cache-Control Headers w HTTP 1.1. W związku z powyższym wystarczające jest zastosowanie samych Cache-Control; oferują one więcej możliwości. W wypadku gdy strona korzysta z obu rozwiązań i podają one sprzeczne wartości, przeglądarki i serwery dadzą pierwszeństwo zasadom opisanym w sekcji Cache-Control. Czy zatem jest powód, aby korzystać z Expire Headers równocześnie z Cache-Control?

Możemy założyć, że nie wszystkie przeglądarki i serwery potrafią prawidłowo parsować Cache-Control, dlatego wtedy jako alternatywę do dyspozycji pozostawiamy Expire Headers. Jest to jednakże rozwiązanie opcjonalne i równie dobrze może zawierać zasady korzystania z pamięci podręcznej tylko dla najważniejszych zasobów. O optymalizacji za pomocą Cache-Control przeczytać można także w przewodniku dla deweloperów Google w dziale Buforowanie HTTP.

Cache-control w praktyce

Poniżej przykładowy kod sekcji Cache-Control w .HTACCESS

#początek modułu
<IfModule mod_headers.c>

#rok ważności dla grafik, zasób publiczny
<FilesMatch „.(jpg|jpeg|png|gif|ico)$”>
Header set Cache-Control „max-age=31536000, public”
</FilesMatch>

#miesiąc ważności dla SWF, zasób publiczny
<FilesMatch „.(swf)$”>
Header set Cache-Control „max-age=2628000, public”
</FilesMatch>

#miesiąc ważności dla CSS i JS, zasób prywatny
<FilesMatch „.(css|js)$”>
Header set Cache-Control „max-age=2628000, private”
</FilesMatch>

#opcjonalnie można uwzględnić także inne zasoby
<FilesMatch „.(x?html?|php)$”>
Header set Cache-Control „max-age=2628000, private”
</FilesMatch>

</IfModule>
#zakończenie modułu

FilesMatch – określa, jakich zasobów ma dotyczyć zasada wykorzystania pamięci podręcznej.

Max-age – określa w sekundach, jak długo wybrane zasoby mają być pobierane z pamięci podręcznej:

  • Minuta – max-age=60
  • Godzina – max-age=3600
  • Dzień – max-age=86400
  • Tydzień – max-age=604800
  • Miesiąc – max-age=2628000
  • Rok – max-age=31536000

Dopasowanie okresu wykorzystania pamięci podręcznej do zasobów jest zależne od natury witryny. Webmaster musi określić, jak często dane zasoby są zmieniane i dopasować odpowiednie okresy. Zazwyczaj zasobami, które nie zmieniają się często, to JS (Javascripts) i obrazki. Jeśli nie ma planów na zmiany tych zasobów, można ustawić ich ważność na miesiąc lub nawet rok. Natomiast CSS można bezpiecznie ustawić na tydzień lub miesiąc, gdyż może okazać się, że wprowadzenie nowej zawartości wymaga w nim zmian.

Rozwiązaniem na zasoby o długim okresie ważności, których zawartość jednak musi się zmienić, jest podmiana nazwy pliku. Np. zmiana nazwy nowej grafiki logo.jpg na logo-2.jpg spowoduje, że mimo np. rocznego okresu ważności wszyscy użytkownicy zobaczą nową wersję obrazka bez ingerowania w ogólne zasady Cache-Control.

Private lub Public – ten atrybut określa, czy dany zasób może być zapisywany w pamięci podręcznej wszędzie, czy tylko indywidualnie przez konkretne urządzenie. Większość zasobów można określić jako public, a wyjątkiem będą przede wszystkim zasoby CSS i JS, jako że najczęściej wiążą się np. z indywidualnymi ustawieniami użytkownika na danej witrynie (user specific content) lub wprowadzaniem prywatnych danych do formularzy. Dla bezpieczeństwa zasoby CSS i JS zazwyczaj oznaczamy jako Private. Co więcej, tylko w tym wypadku PageSpeed Insights uzna je za zoptymalizowane. Oczywiście dopasowanie zasobów do Private i Public również jest indywidualne dla każdej witryny i to webmaster powinien podjąć decyzję, jaki podział w danym wypadku będzie najlepszy.

Expire headers w praktyce

Poniżej przykładowy kod sekcji Expire headers w .HTACCESS:

#rozpoczęcie modułu
<IfModule mod_expiers.c>
ExpiresActive on

#zasada ogólna ważności zasobów – używając tej zasady, bardzo ważne jest, żeby w dalszej części modułu uwzględnić WSZYSTKIE zasoby, które mają mieć inny okres ważności. Dlatego zasada ta powinna być używana z wyjątkową ostrożnością

ExpiresDefault „access plus 1 day”
#bezpiecznym ustawieniem jest  też
ExpiresDefault „access plus 0 seconds”

#grafiki, wideo, audio dla wybranych formatów
ExpiresByType image/gif „access plus 1 year”
ExpiresByType image/png  „access plus 1 year”
ExpiresByType image/jpg „access plus 1 year”
ExpiresByType image/jpeg „access plus 1 year”
ExpiresByType image/x-icon „access plus 1 year”
ExpiresByType video/mp4 „access plus 1 month”
ExpiresByType audio/mp3 „access plus 1 month”

#CSS i JS
ExpiresByType application/javascript „access plus 1 year”
ExpiresByType text/javascript „access plus 1 year”
ExpiresByType text/css „access plus 1 year”

#inne
ExpiresByType text/xml „access plus 1 day”
ExpiresByType text/html „access plus 1 day”
ExpiresByType application/xhtml+xml „access plus 1 day”

</IfModule>
#zakończenie modułu

W kwestii dopasowania zasobów i czasu ich przechowywania obowiązują te same zasady co w wypadku Cache-Control. Wartości te powinny być indywidualnie dopasowane do specyfiki witryny.

Rezultaty wykorzystywania pamięci podręcznej

Rezultaty wprowadzenia Cache-Control są indywidualne dla każdej witryny. Jeśli już wcześniej była dobrze zoptymalizowana, wykorzystanie pamięci podręcznej podniesie wynik optymalizacji o 1-3 pkt, natomiast jeśli optymalizacja była słaba i cache w żaden sposób nie był wykorzystywany, wdrożenie potrafi podnieść wynik nawet o 15-20 punktów jednocześnie wpływając pozytywnie na szybkość działania strony dla powracających użytkowników.

Kompresja GZIP

Kompresja GZIP potrafi znacznie zmniejszyć ilość pobieranych danych. Serwer wysyła do przeglądarki skompresowane pliki, które rozpakowywane są lokalnie. Czy strona korzysta z kompresowania GZIP, można sprawdzić na jednej z darmowych sprawdzarek np. https://checkgzipcompression.com/.

Kompresja GZIP screen

Jeśli strona nie wykorzystuje kompresji GZIP, możemy ją wprowadzić za pomocą pliku .htaccess.

mod_gzip i mod_deflate

Za kompresję mogą odpowiadać 2 moduły – mod_gzip lub mod_deflate. Nie wszystkie serwery je obsługują, więc może okazać się, że mimo wprowadzenia kodu do .htaccess kompresja nie zacznie działać na żadnym z nich. W takim przypadku zalecany jest kontakt z dostawcą hostingu.

mod_gzip do .htaccess

#rozpoczęcie modułu GZIP
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes

#określenie zasobów do kompresji
mod_gzip_item_include file .(html?|txt|css|js)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>
#zakończenie modułu GZIP

mod_defalte do .htaccess

#rozpoczęcie modułu DEFLATE
<IfModule mod_deflate.c>
#określenie zasobów do kompresji
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
#zakończenie modułu

Kompresja plików graficznych

Pliki graficzne powinny być odpowiednio kompresowane niezależnie od wykorzystania modułu gzip w .htaccess. Odpowiedni dobór formatów (progressive JPEG, WEBP, PNG), ich poziomu kompresji oraz rozmiarów wyklucza potrzebę ponownej kompresji skompresowanych już zasobów.

Rezultaty wykorzystania kompresji

Kompresja wpływa pozytywnie zarówno na wynik w PageSpeed Insights, jak i faktyczną szybkość wczytywania stron, istotnie zmniejsza rozmiary plików, które pobiera przeglądarka. W wynikach PageSpeed Insights odpowiednio wdrożona kompresja potrafi poprawić wynik nawet o 20-30 punktów.

Przekierowania

Wykorzystywanie przekierowań 301 jest dla wielu witryn na porządku dziennym. Najpopularniejsze przekierowania dotyczą:

  • Protokołu SSL – przekierowanie przenosi stronę z HTTP na HTTPS,
  • Przedrostka „www” witryny – 301 przenosi użytkownika na pożądaną wersję z lub bez „www”.

Wiele witryn wykorzystuje oba te przekierowania błędnie. Przykład:

  • http://przyklad.pl > 301 > https://przyklad.pl > 301 > https://www.przyklad.pl.

Występują tutaj dwa przekierowania, które negatywnie wpływają na PageSpeed i realny czas otwierania strony. Zalecanym rozwiązaniem jest wdrożenie jednego przekierowania:

  • http://przyklad.pl > 301 > https://www.przyklad.pl

lub jeśli preferowana jest wersja bez „www”:

  • http://www.przyklad.pl > 301 > https://przyklad.pl

Przekierowanie 301 w .htaccess

Poniższy kod wprowadzony do .htaccess spowoduje, że za pomocą jednego przekierowania 301 docelowym adresem będzie https://przyklad.pl.

#rozpoczęcie modułu kierującego na HTTPS, bez „www”
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
#zakończenie modułu

Oraz wersja, która kieruje na HTTPS oraz wersję uwzględniającą „www” (https://www.przyklad.pl):

#rozpoczęcie modułu kierującego na HTTPS, z „www”
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www.(.*)$ [NC]
RewriteRule ^(.*)$ https://www.%1/$1 [R=301,L]
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ /$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
#zakończenie modułu

Rezultaty skrócenia przekierowań

Skrócenie ścieżki przekierowań z 2-3 do 1 potrafi podnieść PageSpeed o ponad 10 punktów i przyspieszyć realne wczytywanie strony.

optymalizacja pagespeed

Optymalizacja wyników PageSpeed Insights i nadchodzący Speed Update

Google zapowiedziało, że nadchodzący update dotyczyć ma tylko wąskiej grupy witryn działających wolno i osiągających słabe wyniki w PSI dla urządzeń mobilnych. Co dokładnie znaczy „wolno”? Tego Google nie powiedziało, nie ma podanej granicy w wyniku optymalizacji albo czasie wczytywania strony, poniżej której strona będzie spadać w mobilnym rankingu. Warto zatem przygotować się zawczasu do nadchodzącej aktualizacji, sprawdzić wyniki swojej witryny oraz zweryfikować, jakie optymalizacje sugeruje Google. Jeśli wyniki są średnie lub słabe, a w zaleceniach widnieją między innymi wskazówki dotyczące pamięci podręcznej i kompresji, powyższe rozwiązania mogą szybko usunąć problem.