Largest Contentful Paint mierzy, kiedy w widocznej części strony pojawia się jej największy element. Na stronach z grafiką prawie zawsze jest nim obraz, a najprostszą metodą przyspieszenia tego momentu jest <link rel="preload"> — informacja dla przeglądarki, żeby zaczęła pobierać plik, zanim dojdzie do niego w kodzie strony.

Metoda działa pod jednym warunkiem: trzeba wskazać właściwy plik. I tu zaczyna się problem, bo wskazanie go z kodu strony jest zgadywaniem.

Dlaczego heurystyka z kodu strony zawodzi

Który obraz jest największym elementem, zależy od szerokości ekranu, od tego, co jest schowane, i od tego, co dorysuje JavaScript. Ten sam szablon na telefonie i na monitorze daje dwa różne zwycięzcy. Reguła w rodzaju „pierwszy obraz w treści” trafia dobrze na stronie głównej i chybia wszędzie indziej.

Pobranie z wyprzedzeniem niewłaściwego pliku jest gorsze niż niepobranie niczego: zabiera pasmo temu obrazowi, który naprawdę decyduje o wyniku.

To dlatego traktujemy tę decyzję jak pomiar, a nie jak konfigurację.

Reguła, która bierze się z odsłon

Przeglądarka potrafi powiedzieć wprost, który element uznała za największy — udostępnia to przez PerformanceObserver. Zbieramy te zgłoszenia z prawdziwych odsłon i na ich podstawie budujemy regułę pobierania z wyprzedzeniem, osobno dla telefonu i osobno dla monitora.

  • Reguła zaczyna działać dopiero po trzech zgodnych pomiarach — jedna odsłona z nietypowego urządzenia nie przestawia serwisu.
  • Reguła wygasa sama, kiedy plik zniknie albo gdy przez trzydzieści dni nikt jej nie potwierdzi. Po przebudowie strony głównej stara reguła nie zostaje w bazie jako pobieranie nieistniejącego obrazu.
  • Podział na telefon i monitor jest twardy, bo to dwa różne układy, a nie ten sam z inną szerokością.

Tła w CSS to osobny przypadek

Obraz ustawiony przez background-image nie przechodzi przez żaden filtr systemu zarządzania treścią. Nie ma srcset, nie stosuje się do niego <picture>, a przeglądarka dowiaduje się o jego istnieniu dopiero po przetworzeniu arkusza stylów — czyli najpóźniej, jak się da.

Takie tła rejestrujemy jawnie: motyw zgłasza je filtrem, a warstwa wydajnościowa składa z tego image-set() z zapasową wersją dla starszych przeglądarek i, jeśli trzeba, dokłada pobieranie z wyprzedzeniem. Rejestracja jest bezwarunkowa, żeby panel mógł pokazać listę wszystkich takich teł; osobna decyzja odpowiada na pytanie, na których podstronach mają obowiązywać.

Publiczny punkt odbioru pomiarów i jego zabezpieczenia

Pomiary muszą trafić na serwer z każdej odsłony, także tej serwowanej z pamięci podręcznej. Znacznik jednorazowy tego nie przetrwa — wygenerowany przy zapisie strony do pamięci, po godzinie jest już nieważny dla wszystkich, którzy tę stronę dostają. Punkt odbioru musi więc być publiczny, a skoro jest publiczny, musi sprawdzać wszystko inne.

  • Zasób musi leżeć w katalogu wgranych plików tego serwisu. Obcy adres w znaczniku pobierania z wyprzedzeniem oznaczałby, że każda odsłona strony melduje się na cudzym serwerze — razem z adresem IP odwiedzającego.
  • Nagłówek Referer musi wskazywać ten sam serwis i ten sam adres, co zgłoszenie.
  • Sześćdziesiąt zgłoszeń na godzinę z jednego adresu IP.

Konwersja obrazów bez usługi zewnętrznej

Drugą połową tej samej pracy jest format plików. WebP potrafi zdjąć z obrazu połowę wagi, a konwersję wykonujemy biblioteką graficzną na tym samym serwerze, który wydaje stronę. Bez klucza do zewnętrznej usługi, bez konta, bez limitów i bez wysyłania zdjęć klienta na cudzą infrastrukturę.

Pliki zapisujemy, dopisując rozszerzenie: zdjecie.jpg.webp, nie zdjecie.webp. Powód jest prozaiczny i wychodzi dopiero na prawdziwych bibliotekach mediów — zdjecie.jpg i zdjecie.png w jednym katalogu to normalna sytuacja, a podmiana rozszerzenia sklejałaby oba w jeden plik.

Od pomiaru do szybszej strony

  1. ZmierzSprawdź rzeczywisty element LCP na telefonie i komputerze.
  2. DobierzPobieraj z wyprzedzeniem obraz wskazany przez zgodne pomiary.
  3. WeryfikujWygaszaj nieaktualne reguły, gdy zmieniają się obrazy lub układ strony.