- Przygotuj wiarygodne środowisko pomiarowe
- Ustal cel, zakres i hipotezy
- Standaryzuj warunki testów
- Dobierz narzędzia i metryki
- Przygotuj procedurę pomiarową
- Analiza przeglądarki i krytycznej ścieżki
- Odczytywanie waterfall i osi czasu
- Blokady wątku głównego i skrypty
- Priorytety zasobów i wskazówki ładowania
- Obrazy, czcionki, krytyczny CSS
- Minimalizacja i kompresja
- Sieć, DNS, TLS, edge i dystrybucja treści
- Diagnozuj opóźnienia sieciowe
- Skuteczna konfiguracja CDN
- Nagłówki sterujące buforowaniem
- Minimalizacja liczby i kosztu połączeń
- Serwer aplikacyjny i baza danych
- Śledzenie żądań i profilowanie
- Logi i metryki infrastruktury
- Baza danych: zapytania, indeksy, wzorce dostępu
- Architektura i przepływy danych
- Pliki, storage i generowanie treści
- Utrzymanie, regresje i praca ciągła
- RUM, alerty i ciągły monitoring
- Budżety wydajności w CI/CD
- Diagnostyka regresji
- Runbooki i gotowość na incydenty
- Kultura i edukacja
Powolna strona potrafi zniszczyć konwersję, pozycje SEO i cierpliwość użytkowników. Zamiast łatać przypadkowe elementy, przejdź przez metodyczną analizę: zbierz wiarygodne dane, odtwórz problem i ustal, gdzie uciekają milisekundy — w przeglądarce, sieci, serwerze czy bazie. Ta instrukcja prowadzi krok po kroku: od przygotowania środowiska pomiarowego, przez czytanie wykresów waterfall i logów, po decyzje, które realnie poprawiają szybkość w sposób przewidywalny i powtarzalny.
Przygotuj wiarygodne środowisko pomiarowe
Ustal cel, zakres i hipotezy
Zanim otworzysz jakiekolwiek narzędzie, doprecyzuj, co oznacza “wolna strona” w Twoim przypadku. Może chodzić o pierwsze wrażenie użytkownika, pełną interaktywność, czas odpowiedzi API lub płynność przewijania. Zdefiniuj 2–3 hipotezy, np.: “kluczowy jest czas odpowiedzi serwera”, “obrazy są zbyt ciężkie”, “strona blokowana jest przez skrypty zewnętrzne”. To pozwoli zawęzić analizę i uniknąć przypadkowych zmian.
Standaryzuj warunki testów
Aby wyniki były porównywalne, testuj w kontrolowanych warunkach:
- Urządzenie: desktop o stałej specyfikacji oraz średniej klasy telefon (emulacja lub fizyczny).
- Sieć: ogranicz przepustowość i opóźnienia (np. 10 Mbps/4G, 150 ms RTT), wyłącz VPN-y i aplikacje generujące ruch.
- Widok: mierz osobno Pierwsze Wejście (cold start) i powtórne wizyty (z ciepłą pamięcią podręczną).
- Wersje: oznaczaj commit/release, aby powiązać wyniki z konkretną wersją kodu.
Dobierz narzędzia i metryki
Połącz pomiary syntetyczne i dane z realnych użytkowników (RUM):
- Chrome DevTools Performance/Network do szczegółowej analizy wykresów i blokad wątku głównego.
- Lighthouse/PageSpeed do audytu oraz automatyzacji w CI.
- WebPageTest dla porównania różnych lokalizacji i sieci oraz nagrań wideo.
- RUM (np. GA4, Sentry, własny skrypt) dla rozkładu wyników w realnym świecie.
Monitoruj m.in. TTFB, FCP, FID/INP, CLS i LCP, bo to one najczęściej korelują z percepcją szybkości i SEO. Dokumentuj również rozmiar HTML, liczbę żądań, procent trafień w cache przeglądarki i CDN oraz błędy sieciowe.
Przygotuj procedurę pomiarową
Stwórz checklistę, aby każdy test wyglądał identycznie:
- Odśwież z pominięciem pamięci przeglądarki, następnie wykonaj 2–3 powtórzenia.
- Oddziel testy zimne (brak pamięci podręcznej) od ciepłych (po jednej wizycie).
- Rejestruj HAR, zrzuty ekranu i wyniki Lighthouse; zapisuj parametry sieci i urządzenia.
- Upewnij się, że strona ładowana jest z produkcyjnej konfiguracji i bez dodatkowych wtyczek deweloperskich.
Analiza przeglądarki i krytycznej ścieżki
Odczytywanie waterfall i osi czasu
Wykres waterfall porządkuje żądania według czasu. Szukaj długich barów i zależności blokujących. Sprawdź: kiedy rusza pierwsze pobranie HTML, długość DNS/TLS/Connect, kolejki HTTP/2/3, oraz czy zasoby o wysokim priorytecie nie czekają za mniej ważnymi.
W osi Performance zobaczysz rozkład pracy wątku głównego i momenty FCP, LCP, interaktywność. Jeżeli największy element (obraz, blok hero) pojawia się późno, zbadaj, co opóźnia jego wczytanie i renderowanie: kolejność ładowania, CSS blokujący, skrypty lub priorytety sieciowe.
Blokady wątku głównego i skrypty
- Wyszukaj Long Tasks (powyżej 50 ms), które “zamrażają” UI. Mogą wynikać z ciężkich bibliotek, parsowania ogromnych JSON-ów, pracy polifillów lub nieoptymalnych pętli.
- Sprawdź zakładkę Coverage: ile kodu JS/CSS jest nieużywane podczas startu. Nadmiarowa paczka spowalnia parsowanie i kompilację.
- Oceń skrypty stron trzecich (tag manager, chat, analityka). Ogranicz liczbę, wczytuj je później lub poprzez serwerową proxyzację.
- Podziel bundel na krytyczny i niekrytyczny, ładuj moduły on demand, korzystaj z dynamic import i deferral.
Priorytety zasobów i wskazówki ładowania
- Zadbaj o odpowiednie priorytety: HTML i krytyczny CSS jako najwyższe, obraz LCP — preload, czcionki — preload z właściwą wagą i formatami.
- Używaj preconnect/dns-prefetch do domen, z których pobierasz kluczowe zasoby.
- Skorzystaj z Priority Hints (importance=high/low), aby podpowiedzieć przeglądarce znaczenie konkretnych zasobów.
- Upewnij się, że importy CSS nie są zagnieżdżone i nie opóźniają malowania.
Obrazy, czcionki, krytyczny CSS
- Obrazy: responsywne srcset/sizes, formaty WebP/AVIF, przycięcie do faktycznego rozmiaru, lazy-loading poza viewportem, kompresja bezstratna/stratna.
- Czcionki: preload dla najważniejszych wariantów, font-display: swap, podzbiór znaków (subset), lokalna pamięć i strategia rezerwowa.
- Krytyczny CSS: wyodrębnij style potrzebne do pierwszego widoku i wstrzyknij inline; resztę doładuj asynchronicznie.
Minimalizacja i kompresja
- Włącz Brotli lub gzip dla HTML, CSS, JS; sprawdź, czy nagłówki nie wykluczają kompresji dla HTTPS.
- Usuń duplikaty stylów i skryptów, korzystaj z tree-shaking i minifikacji, ogranicz polifille do rzeczywiście potrzebnych przeglądarek.
- Zadbaj o ETag/Last-Modified i długie czasy życia dla statyk — późniejsze wizyty będą znacznie szybsze.
Sieć, DNS, TLS, edge i dystrybucja treści
Diagnozuj opóźnienia sieciowe
Rozbij pierwszy kontakt na: DNS lookup, TLS handshake, TCP/TQUIC connect, transfer. Wysoka latencja sugeruje odległość geograficzną, przeciążenie łącza lub wolne TLS/ALPN. Zmierz RTT z kilku kontynentów. Jeśli TTFB jest umiarkowane lokalnie, a wysokie globalnie — treści i serwer są zbyt daleko od użytkownika.
Skuteczna konfiguracja CDN
- Zidentyfikuj procent HIT/MISS/BYPASS. Przy dużym odsetku MISS popraw TTL, klucze Vary i zgodność etagów.
- Ustal zasady cache’owania dla HTML (krótsze TTL, stale-while-revalidate), a dla statyk — długie TTL i unikalne nazwy plików (hash w nazwie).
- Wykorzystaj edge rules: kompresja, transformacje obrazów, automatyczny WebP, optymalizacja czcionek.
- Włącz HTTP/3/QUIC i 0-RTT, jeśli dostawca to wspiera; to często poprawia start na mobilnym łączu.
Nagłówki sterujące buforowaniem
- Cache-Control: public/private, max-age, s-maxage, stale-while-revalidate, stale-if-error.
- ETag/Last-Modified dla walidacji; upewnij się, że generują się deterministycznie (bez losowych sufiksów).
- Vary tylko na potrzebne pola (np. Accept-Encoding, Accept), aby uniknąć rozwadniania pamięci podręcznej.
Minimalizacja liczby i kosztu połączeń
- Agreguj zasoby na tych samych domenach, unikaj nadmiarowych hostów trzecich.
- Włącz HTTP keep-alive/connection reuse i weryfikuj, czy nie tworzysz nowych połączeń przez przekierowania lub błędne CORS.
- Dla skryptów zewnętrznych rozważ serwerową proxyzację (z rozwagą), aby objąć je własną kontrolą TTL i kompresji.
Serwer aplikacyjny i baza danych
Śledzenie żądań i profilowanie
Załóż APM lub tracing end-to-end, by zobaczyć, gdzie faktycznie spędzasz czas: middleware, kontrolery, szablony, zapytania do API, wywołania bazodanowe, operacje na plikach. Oznaczaj kluczowe endpointy i łącz ślady z identyfikatorem żądania widocznym w logach frontowych.
- Mierz cold vs warm start aplikacji (np. inicjalizacja frameworka, kontener DI, ładowanie konfiguracji).
- Wykrywaj locki i wąskie gardła (muteksy, sekcje krytyczne, zablokowane pule połączeń).
- Analizuj szczyty GC i pauzy (JVM, Node, .NET), które mogą zwiększać czas odpowiedzi.
Logi i metryki infrastruktury
- Access log: rozkład czasów, kody 5xx/4xx, geografia, user-agenty, outliery i wzorce godzinowe.
- Error log: wyjątki, time-outy, błędy połączeń do usług zewnętrznych, limity zasobów.
- System: CPU, RAM, IO wait, sieć, otwarte pliki, liczba procesów/workerów; dostrajaj puli wątków i limity.
- Kolejki: długość i czas przetwarzania (np. email, generacja PDF), które mogą blokować żądania synchroniczne.
Baza danych: zapytania, indeksy, wzorce dostępu
Najczęstsze spowolnienia wynikają z wolnych zapytań i nieefektywnej struktury danych. Włącz slow query log i używaj EXPLAIN, aby zrozumieć plany wykonania. Zweryfikuj indeksowanie kolumn używanych w WHERE/JOIN/ORDER BY. Szukaj wzorca N+1, nadmiarowych JOIN-ów i zbyt szerokich SELECT-ów.
- Dodaj brakujące indeksy, usuń martwe, rozważ indeksy złożone i partiowe.
- Cache wyników często powtarzanych zapytań (warstwa aplikacyjna lub Redis), invalidacja po zapisie.
- Używaj paginacji po stabilnym kluczu (keyset), unikaj OFFSET przy dużych tabelach.
- Dopasuj rozmiar połączeń i puli (pool), aby nie dusić bazy i nie wchodzić w thrashing.
Architektura i przepływy danych
- Oddziel ścieżki synchroniczne (dla użytkownika) od asynchronicznych (kolejki, CRON), aby skrócić czas odpowiedzi.
- Stosuj lokalny i rozproszony cache dla drogich operacji; pamiętaj o strategiach wygaszania i wersjonowaniu kluczy.
- Walcz z trafieniami w zimny start: prewarm cache, utrzymuj stałą liczbę workerów, redukuj rozruch frameworka.
- Oceń wpływ usług zewnętrznych (płatności, antyboty, reklamy) i konfiguruj time-outy oraz circuit breakers.
Pliki, storage i generowanie treści
- Przenieś duże pliki i obrazy na storage obiektowy z CDN; serwuj tylko podpisane, skompresowane warianty.
- Generuj HTML statycznie dla stron niezmiennych lub rzadko aktualizowanych (SSG, prerender), a dynamiczne dane dogrywaj klientem.
- W przypadku SSR minimalizuj I/O szablonów, cache’uj fragmenty (ESI, partials) i agreguj zapytania.
Utrzymanie, regresje i praca ciągła
RUM, alerty i ciągły monitoring
Narzędzia RUM dostarczają rozkładu wyników w realnym świecie: p50/p75/p95, rozbicie na kraj, urządzenie, sieć, wersję aplikacji. Zdefiniuj budżety wydajności i progi alertów dla LCP/INP/CLS, TTFB i błędów JS. Buduj dashboardy, które łączą metryki frontu, sieci, serwera i bazy w jeden strumień.
Budżety wydajności w CI/CD
- Automatyzuj Lighthouse w pipeline; przerwij build, jeśli rozmiar bundla lub metryki przekroczą budżet.
- Waliduj nagłówki cache i kompresji w testach integracyjnych (np. brak kompresji = fail).
- Weryfikuj rozmiar i liczbę zasobów krytycznych na kluczowych ścieżkach (home, listing, checkout).
Diagnostyka regresji
- Porównuj HAR i profile przed/po wdrożeniu; szukaj różnic w priorytetach i krytycznych zasobach.
- Wykorzystaj feature flags/canary do kontrolowanego rollout’u; jeśli metryki spadają, szybko wycofuj zmiany.
- Używaj git bisect do zawężania regresji wydajności, a testy A/B do weryfikacji hipotez.
Runbooki i gotowość na incydenty
- Stwórz runbook: gdzie sprawdzić logi, które dashboardy otworzyć, jak zwiększyć zasoby i jak przełączyć ruch.
- Przećwicz scenariusze: degradacja bazy, awaria CDN, skok ruchu z kampanii, błąd w deployu.
- Po incydencie rób postmortem z konkretnymi działaniami naprawczymi i zadaniami w backlogu.
Kultura i edukacja
- Włącz wydajność do Definition of Done: testy, budżety, weryfikacja nagłówków, analiza kluczowych metryk.
- Edukacja zespołu: czytanie waterfall, rozumienie krytycznej ścieżki, narzędzia APM i profilery przeglądarki.
- Regularne przeglądy: audyty kwartalne, przeglądy konfiguracji CDN, przegląd zapytań w slow logu.
Stosując powyższy proces — od pomiarów, przez analizę przeglądarki, sieci i serwera, po bazę danych i dystrybucję treści — odnajdziesz źródła opóźnień i zaplanujesz działania, które przyniosą szybki i trwały efekt. Priorytetyzuj według wpływu na użytkownika i kosztu wdrożenia, a każdą zmianę weryfikuj rzetelnymi pomiarami, aby uniknąć regresji i utrzymać stabilny wzrost jakości doświadczenia.