Przez długi czas zakładałem, że wysokie wyniki Lighthouse są głównie rezultatem optymalizacji. Kompresowanie obrazów, odraczanie skryptów, naprawianie przesunięć układu, dostosowywanie motywów, wymiana wtyczek i powtarzanie cyklu za każdym razem, gdy pojawia się nowe ostrzeżenie.
Z czasem to założenie przestało pasować do tego, co obserwowałem w praktyce.
Strony, które konsekwentnie uzyskiwały dobre wyniki, nie były tymi, w które włożono najwięcej wysiłku optymalizacyjnego. Były to te, w których przeglądarka po prostu miała mniej pracy do wykonania.
W tym momencie Lighthouse przestał być narzędziem optymalizacji, a stał się sygnałem diagnostycznym dla wyborów architektonicznych.
Lighthouse nie ocenia frameworków ani narzędzi. Ocenia rezultaty.
Jak szybko pojawia się znacząca treść.
Ile JavaScript blokuje główny wątek.
Jak stabilny pozostaje układ podczas ładowania.
Jak dostępna i indeksowalna jest struktura dokumentu.
Te rezultaty są efektami decyzji podjętych znacznie wcześniej w stosie. W szczególności odzwierciedlają, ile obliczeń jest odraczanych do przeglądarki w czasie wykonywania.
Gdy strona zależy od dużego pakietu po stronie klienta, aby stać się użyteczna, słabe wyniki nie są zaskoczeniem. Gdy strona składa się głównie ze statycznego HTML z ograniczoną logiką po stronie klienta, wydajność staje się znacznie bardziej przewidywalna.
W audytach, które przeprowadziłem, i projektach, nad którymi pracowałem, wykonywanie JavaScript jest najczęstszym źródłem regresji Lighthouse.
Nie dlatego, że kod jest niskiej jakości. To dlatego, że JavaScript konkuruje o jednowątkowe środowisko wykonawcze podczas ładowania strony.
Środowiska uruchomieniowe frameworków, logika hydratacji, wykresy zależności i inicjalizacja stanu - wszystko to zużywa czas, zanim strona stanie się interaktywna. Nawet małe funkcje interaktywne często wymagają nieproporcjonalnie dużych pakietów.
Architektury, które domyślnie zakładają JavaScript, wymagają ciągłego wysiłku, aby utrzymać wydajność pod kontrolą. Architektury, które traktują JavaScript jako świadomy wybór, mają tendencję do generowania bardziej stabilnych rezultatów.
Wstępnie wyrenderowane wyjście usuwa kilka zmiennych z równania wydajności.
Nie ma kosztu renderowania po stronie serwera w czasie żądania.
Nie jest wymagane uruchomienie po stronie klienta, aby treść się pojawiła.
Przeglądarka otrzymuje przewidywalny, kompletny HTML.
Z perspektywy Lighthouse poprawia to metryki takie jak TTFB, LCP i CLS bez wymagania ukierunkowanej pracy optymalizacyjnej. Generowanie statyczne nie gwarantuje idealnych wyników, ale znacznie zawęża zakres możliwych awarii.
Przed przebudową mojego osobistego bloga zbadałem kilka popularnych podejść, w tym konfiguracje oparte na React, które domyślnie polegają na hydratacji. Były elastyczne i wydajne, ale wydajność wymagała ciągłej uwagi. Każda nowa funkcja wprowadzała pytania dotyczące trybu renderowania, pobierania danych i rozmiaru pakietu.
Z ciekawości wypróbowałem inne podejście, które zakładało statyczny HTML w pierwszej kolejności i traktowało JavaScript jako wyjątek. Wybrałem Astro do tego eksperymentu, ponieważ jego domyślne ograniczenia pasowały do pytań, które chciałem przetestować.
To, co się wyróżniało, to nie dramatyczny początkowy wynik, ale jak mało wysiłku było potrzebne do utrzymania wydajności w czasie. Publikowanie nowych treści nie wprowadzało regresji. Małe elementy interaktywne nie powodowały niepowiązanych ostrzeżeń. Poziom bazowy był po prostu trudniejszy do osłabienia.
Udokumentowałem proces budowy i kompromisy architektoniczne w osobnej notatce technicznej podczas pracy nad tym eksperymentem na osobistym blogu z idealnym wynikiem Lighthouse.
To podejście nie jest uniwersalnie lepsze.
Architektury statyczne nie są idealne dla wysoce dynamicznych aplikacji stanowych. Mogą komplikować scenariusze, które w dużym stopniu polegają na uwierzytelnionych danych użytkowników, aktualizacjach w czasie rzeczywistym lub złożonym zarządzaniu stanem po stronie klienta.
Frameworki, które zakładają renderowanie po stronie klienta, oferują większą elastyczność w tych przypadkach, kosztem wyższej złożoności w czasie wykonywania. Chodzi nie o to, że jedno podejście jest lepsze, ale o to, że kompromisy są bezpośrednio odzwierciedlone w metrykach Lighthouse.
To, co ujawnia Lighthouse, to nie wysiłek, ale entropia.
Systemy, które opierają się na obliczeniach w czasie wykonywania, gromadzą złożoność w miarę dodawania funkcji. Systemy, które wykonują więcej pracy w czasie budowy, ograniczają tę złożoność domyślnie.
Ta różnica wyjaśnia, dlaczego niektóre strony wymagają ciągłej pracy nad wydajnością, podczas gdy inne pozostają stabilne przy minimalnej interwencji.
Wysokie wyniki Lighthouse rzadko są rezultatem agresywnych przebiegów optymalizacji. Zwykle wynikają naturalnie z architektur, które minimalizują to, co przeglądarka musi zrobić podczas pierwszego załadowania.
Narzędzia przychodzą i odchodzą, ale podstawowa zasada pozostaje ta sama. Gdy wydajność jest domyślnym ograniczeniem, a nie celem, Lighthouse przestaje być czymś, za czym się goni, a staje się czymś, co się obserwuje.
Ta zmiana ma mniej wspólnego z wyborem odpowiedniego frameworka, a bardziej z wyborem miejsca, w którym złożoność może istnieć.


