Mateusz Mazurek – programista z pasją

Czyli o użyciu Pythona i kilku innych technologii do tworzenia świetnej jakości aplikacji w oparciu o stabilny proces dostarczania oprogramowania.

Felietony/inne Inne Programowanie webowe

Jak zwiększyłem szybkość bloga dwukrotnie?

Cześć!

Historia rozpoczęła się na początku czerwca. Wtedy to na Instagramie obejrzałem story o szybkości stron internetowych. Pojawiło się tam narzędzie PageSpeed Insights. Narzędzie znałem, ale już od jakiegoś czasu nie używałem. Ze story wynikało, że zmienił się algorytm oceny szybkości, więc zaciekawiło mnie, jaki wynik ma mój blog.

Wszedłem więc na PageSpeed Insights.

Wpisałem adres bloga…

I oniemiałem. Bo według Google’a blog był ledwo używalny. Wynik to 47/100.

Znając podstawy SEO, łatwo połączyłem kropki: przecież szybkość strony przekłada się na jej widoczność w wyszukiwarce! Jako autorowi zależy mi na dotarciu do szerokiego grona czytelników. Zmotywowało mnie to zatem do poprawienia tego wyniku.

Stan zastany

Blog jest hostowany na zarządzanym przeze mnie serwerze VPS. Pod spodem, jak to WordPress, ma bazę MariaDB i PHP7, serwowanego jako php-fpm przez nginx’a.

Sam blog ma kilkanaście wtyczek. Stan zastany obejmował jedną wtyczkę, która już wtedy mocno zwiększała szybkość strony. Wtyczka ta dostarcza lazy loading obrazków – ładowała je w momencie, kiedy użytkownik przescrollował do obrazka, nie zaś od razu po otworzeniu strony.

Blog na froncie ma CloudFlare.

I to w sumie tyle.

Założenia

Podstawowe założenie brzmiało: nie chcę zmieniać wyglądu bloga. Nie chcę z niczego na nim rezygnować.

Z tym postanowieniem zacząłem dłubać…

Nginx

Zacząłem od serwera HTTP. Podrasowałem trochę konfigurację, ale to co najważniejsze – włączyłem kompresję gzip. Nie odczułem ogromnej różnicy, ale sądzę, że to przez CloudFlare’a.

CloudFlare

Zerknąłem na swoją konfigurację CF’a. Okazało się, że mogę włączyć tam:

  • kompresję algorytmem brotli (nie będę tu go opisywał, ale zachęcam do poszukania w Internecie, czym jest),
  • Rocket Loader (cytując CF’a: Rocket Loader improves paint times by asynchronously loading your Javascripts, including third party scripts, so that they do not block rendering the content of your pages.),
  • znacznie zwiększyłem TTL na cache’u, co pozwala przeglądarce dłużej trzymać pliki na dysku, dzięki czemu powracający użytkownicy mogą ładować części bloga z dysku, a nie przez internet,
  • włączyłem HTTP/3 (with QUIC) – również zachęcam by doczytać.

Zmiany w WordPress

Dotychczas miałem pozytywne zdanie o tym CMSie. Po walce entuzjazm opadł.

Zacząłem od przeglądu wtyczek i usunięcia tych, które nie są mi potrzebne. Usunąłem aż jedną.

Inną wtyczkę wymieniłem na lżejszy odpowiednik.

Minifikacja i połączenie plików JS i CSS

Wiedziałem od zawsze, że blog ładuje dość dużo plików JS i CSS, co szybko skierowało mnie w stronę minifikacji i merge’owanie plików. Tłumacząc na polski: doinstalowałem wtyczkę, która bierze moje pliki z nagłówka, minifikuje (zamienia nazwy zmiennych na krótsze, ucina białe znaki itp) i łączy ze sobą, oszczędzając tym samym ilość zapytań HTTP.

Podobnie sprawa ma się z plikami z dołu pliku HTML oraz z plikami CSS.

Po tych zmianach miałem szybkość na poziomie 55/100.

A ten PHP to musi zawsze wszystko przetwarzać?

Kolejnym, dość oczywistym krokiem, było sprawienie, by PHP nie musiał zawsze od zera przetwarzać mojego bloga. Równie oczywistym pomysłem jest zapisanie po prostu raz wyrenderowanego HTML’a i serwowanie go klientom. Zapewniła mi to wtyczka WP Super Cache.

Mam na tyle farta, że mogę sobie na to pozwolić, bo strona zmienia się relatywnie rzadko. Dodanie każdego wpisu po prostu usuwa cache.

System komentarzy przełączyłem na zapytania AJAXowe, więc komentarze ładuje do DOM’a poza PHPem.

Rozwiązanie ma swoje wady. Czasem zapominasz o tym cache’u i np. zmieniając coś w motywie, dziwisz się, że nie widać tego na blogu.

I już tutaj miałem wynik około 68/100.

Podrasowanie lazy loadingu obrazków

Wtyczka umożliwia określenie, ile px ma być odstępu między wyświetlaną przez użytkownika zawartością, a obrazkiem, by ten zaczął się ładować. Zmniejszyłem trochę tę wartość.

Format obrazków

Szukając innych możliwości optymalizacji, znalazłem sugestie by korzystać z obrazków w formacie webp zamiast jpg, gif itp. Załączam powód:

To pozwoliło mi osiągnąć wynik w okolicach 77/100.

Lazy load v2.0

Analizując bloga doszedłem do wniosku, że lazy load mógłby pojawiać się częściej. Na pierwszy rzut poszedł element, na który bardzo krzyczał PageSpeed Insights. Chodzi o miniaturki książek po prawej.

Książki są obecne w moim życiu od zawsze. Toteż totalnie nie wchodziło w grę ich usunięcie. Niestety, sposób działania wklejki od goodreads jest trochę naiwny. Wklejka, używając document.write, wrzuca do mojego DOMa po prostu elementy <img. To każe przeglądarce wczytać te obrazki…

150 obrazków…

Każdy po ~2kB…

150 oddzielnych requestów HTTP….

Cry Cry GIF - Blackish Crying Cry - Discover & Share GIFs

No tragedia. Aż się prosi, by zwrócili sprite’a!

Niestety, nie zmuszę ich do tego. Ale mogę zrobić lazy load całego widgetu. Nie znalazłem wtyczki, która to zrobi, postanowiłem więc wspiąć się na wyżyny swoich umiejętności w zakresie JSa i napisałem kawałek kodu, który dostarczy taką funkcję.

W ogóle mała dygresja: śmiać mi się chciało, jak pisałem ten kod, bo teraz wszyscy idą w jakieś vue.js, react i tak dalej. A co Mateusz robi? Wpisuje w google „jquery bind doc” :D taki ze mnie frontend developer!

To samo podejście i ten sam kod użyłem do lazy loadu widgetu Facebooka, który jest pod każdym wpisem.

To dało wynik 84/100.


Czekaj, stop!

Podoba Ci się to co tworzę? Jeśli tak to zapraszam Cię do zapisania się na newsletter:
a w ramach prezentu otrzymasz całkowicie za darmo, dwa dokumenty PDF „6 (nie zawsze oczywistych) błędów popełnianych podczas nauki programowania” który jest jednym z efektów ponad siedmioletniej pracy i obserwacji rozwoju niejednego programisty oraz „Wstęp do testowania w Pythonie”, będący wprowadzeniem do biblioteki PyTest.
Jeśli to Cię interesuje to zapraszam również na swoje social media.

Defer i async

Sporo lat minęło od czasu, kiedy dotykałem frontend nieco bardziej niż dopisanie dwu regułek CSS czy kilku tagów HTMLowych. A te kilka lat sporo zmieniło. Doszło wiele fajnych rzeczy, a jedną z nich jest para słów kluczowych: defer i async. Dodaje się je do tagu script i pozwalają one kontrolować moment pobrania i wykonania się objętego tym blokiem kodu JS. Niżej grafika pokazująca, o co chodzi:

Async And Defer Js, HD Png Download , Transparent Png Image - PNGitem

Jak się nietrudno domyślić – słowa te pojawiły się w kodzie źródłowym bloga.

I to na tyle z tych większych rzeczy. Po drodze było kilka mniejszych zmian, ale to te, opisane tutaj, wprowadziły największy skok szybkości. I teraz z dumą patrzę na wynik:

Czy to koniec?

Na bank nie! Rzeczy, które jeszcze mogę zrobić:

  • komunikacja pomiędzy moim serwerem a CloudFlare idzie nieszyfrowanym protokołem HTTP/1.1, można się pokusić o zmianę,
  • mod_speed do nginx – powinno to zdjąć trochę odpowiedzialności z samego WordPressa,
  • poczytać o dns-prefetch, preconnect, prefetch, prerender, subresources, preload i zastanowić się, czy te opcje mi pomogą coś jeszcze ugrać.

Jeśli masz jeszcze jakieś sugestie, to koniecznie napisz w komentarzu o nich! :)

AMP

Wstyd się przyznać, ale do czasu mojej wojenki o optymalnego bloga, nie wiedziałem o istnieniu AMP. Jeśli ktoś też nie wie: AMP jest projektem od Google’a, którego celem jest strukturyzowanie stron oraz ich optymalizacja pod rozwiązania mobilne.

Na fali wcześniejszych zwycięstw dodałem wersję AMP do swojego bloga. Myślicie, że to było tylko zainstalowanie wtyczki? No tak było. Niestety, nim zdecydowałem się, która pozostanie, musiałem przetestować inne i ocenić, jak dużo będę musiał napisać customowego kodu. Nie obyło się bez dopisania własnej wtyczki, która pozwalała zachować w wersji AMP formularz do zapisania się na newsletter. Nie było łatwo, ale jest, blog ma wersję AMP.

Nie ustawiłem domyślnego przekierowania na tę wersję, wdrożyłem ją raczej, by Google odnotował sobie, że ona istnieje. Wiele wskazuje, że pomaga to w kwestii SEO. Zdaję sobie sprawę, że będzie on na nią przekierowywał, ale w tym momencie nie boli mnie to. Myślę, że mam jeszcze czas, by dopracować to rozwiązanie. Na ten moment blog jest w pełni obsługiwalny, zarówno w wersji web jak i mobile/amp.

Zmierzając do brzegu

Mimo że całość prac zajęła spokojnie, zliczając godziny, z 3-4 dni, to sądzę, że było warto. Liczę również, że i Google doceni moje poświęcenie. Nie można zapomnieć o walorach edukacyjnych tej małej wojenki, sporo się dowiedziałem i jeszcze więcej odświeżyłem. A wiedzy nigdy za dużo.

Dzięki za wizytę,
Mateusz Mazurek

A może wolisz nowości na mail?

Subskrybuj
Powiadom o
guest

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

1 Komentarz
Inline Feedbacks
View all comments
Mateusz H.

Niezły upgrade. Fajnie że podzieliłeś się tą wiedzą na swoim blogu Mateusz. Bardzo chętnie z niej skorzystam. Na chwilę obecną mój blog w PageSpeed Insights ma ocenę trochę powyżej 20, :-D. Jest wiele do poprawienia, a zawsze mi się wydawało że nie jest źle :-p. Ostatnio robiłem kurs SEO na Udemy i z raportu SEO między innymi wyszło mi że moje image na blogu są za duże. Zacząłem je kompresować i dużo to dało. Nie wiem skąd w twojej tabelce te image mają ponad 1MB. Mi się to wydaje strasznie dużo. Jak byś chciał to polecam ten kurs na Udemy… Czytaj więcej »