Jak poprawa INP w przypadku Fotocasa przyczyniła się do wzrostu kluczowych danych o 27%

Opublikowano: 14 października 2025 r.

Interakcja do kolejnego wyrenderowania (INP) to kluczowy podstawowy wskaźnik internetowy, który służy do pomiaru responsywności. W 2024 r., gdy INP zastąpił opóźnienie przy pierwszym działaniu (FID), Google Search Console wskazało w przypadku Fotocasa znaczną liczbę stron, które zostały przeniesione do kategorii „Wymaga poprawy” i „Słaby”. W tym studium przypadku opisujemy narzędzia i strategie, które zostały wykorzystane do zdiagnozowania i rozwiązania tych problemów, co w znacznym stopniu poprawiło INP.

Od czego zaczął zespół Fotocasa

Przed zmianą z FID na INP niemal każda strona na komputerach i urządzeniach mobilnych mieściła się w progu „Dobrej jakości”, co oznaczało, że wszystkie podstawowe wskaźniki internetowe (LCP, CLS i FID) działały prawidłowo. Po przejściu na INP prawie wszystkie strony zmieniły stan na „Wymaga ulepszeń”, a niektóre nawet na „Słaba”, ponieważ wartości INP w przypadku większości interakcji użytkowników stale przekraczały 200 milisekund.

Google Search Console pokazujące rozkład adresów URL Fotocasa na komputerach. Po tym, jak INP stał się podstawowym wskaźnikiem internetowym, wiele stron zmieniło stan z „Dobra” na „Wymaga ulepszeń”.
Rys. 1. Google Search Console – rozkład adresów URL Fotocasa na komputerach: gdy zacznie obowiązywać INP, wiele adresów URL wcześniej zaklasyfikowanych jako „dobre” przejdzie do kategorii „wymaga poprawy”.

Dzięki tej zmianie zespół Fotocasa zdał sobie sprawę, że pomijał kluczowy aspekt związany z wygodą użytkowników. FID mierzyło tylko opóźnienie pierwszej interakcji, a INP ocenia czas reakcji na wszystkie interakcje, uwzględniając opóźnienia przetwarzania danych wejściowych i wyświetlania. Ten szerszy zakres pomiarów jest znacznie lepszym przybliżeniem prawdziwej interaktywności (jak stwierdziło Google) i wskazuje utracone możliwości.

Chociaż Google Search Console udostępnia dane o wydajności w terenie, nie zapewnia statystyk w czasie rzeczywistym. Dane są agregowane w okresie 28 dni, co utrudnia dokładne określenie, które interakcje powodowały problemy w danym momencie.

Aby zidentyfikować interakcje, które były najwolniejsze i najczęściej używane przez użytkowników, oraz niezawodnie odtwarzać je w środowiskach deweloperskich zespołu, potrzebny był sposób na śledzenie INP w czasie rzeczywistym. Równie ważne było zrozumienie wpływu wprowadzonych zmian, nie tylko tego, które poprawki pomogły, ale też które zmiany nieumyślnie pogorszyły sytuację.

Z tych powodów do diagnozowania i rozwiązywania problemów użyto zestawu narzędzi. Najważniejsze z nich to:

  • Narzędzia deweloperskie w Google Chrome, a w szczególności karta Wydajność.
  • Niestandardowy system RUM (monitorowanie rzeczywistych użytkowników) stworzony przez zespół Fotocasa w Datadog przy użyciu biblioteki web-vitals.
  • Narzędzia dla programistów React.

Narzędzia do diagnozowania problemu

Do diagnozowania i debugowania problemów z wydajnością INP użyto tych narzędzi:

Narzędzia deweloperskie w Google Chrome

Świetnym sposobem na wykrywanie i odtwarzanie problemów związanych z podstawowymi wskaźnikami internetowymi w aplikacji internetowej jest użycie karty Wydajność w Narzędziach deweloperskich w Google Chrome. Karta Wydajność automatycznie mierzy podstawowe wskaźniki internetowe, zapewniając natychmiastowe informacje zwrotne dotyczące wskaźników wczytywania, interaktywności i przesunięcia układu. Jest on w dużej mierze zgodny z tym, jak te dane są raportowane w innych narzędziach Google.

Karta Wydajność w Narzędziach deweloperskich w Google Chrome, na której widać oś czasu z różnymi wskaźnikami wydajności, takimi jak LCP, FID i CLS, a także aktywność procesora i sieci.
Rys. 2. Karta Wydajność w Narzędziach deweloperskich w Google Chrome.

Aby zidentyfikować i rozwiązać problemy z INP, zespół Fotocasa zwykle zaczynał od ograniczenia wydajności procesora, aby symulować działanie urządzeń z niższej i średniej półki. Dzięki temu zespół Fotocasa mógł obserwować, jak strona zachowuje się w bardziej ograniczonych warunkach. Sesja została następnie zarejestrowana za pomocą profilera, a ślady zostały dokładnie przeanalizowane pod kątem interakcji użytkownika, aby wskazać problemy z wydajnością.

Karta Wydajność w Narzędziach deweloperskich w Google Chrome z menu spowolnienia procesora z opcjami takimi jak „4-krotne spowolnienie” i „6-krotne spowolnienie”.
Rys. 3. Karta Wydajność w Narzędziach deweloperskich w Google Chrome z menu rozwijanym spowolnienia procesora.

Podczas identyfikowania wąskich gardeł szczególnie przydatne jest zbadanie podczęści INP i zadań, które przeglądarka wykonuje w każdej z nich. Na przykład na poniższym obrazie widać, że INP jest dość wysoki z powodu 2 ponownych obliczeń stylu spowodowanych zmianami stylu w treści dokumentu.

Karta Wydajność w Narzędziach deweloperskich w Google Chrome z długim zadaniem w profilerze, którego szczegóły wskazują na 2 ponowne obliczenia stylu powodujące wysoki INP.
Rys. 4. Karta Wydajność w Narzędziach deweloperskich w Google Chrome z wypełnionym profilerem.

Firma Fotocasa skonfigurowała system śledzenia wartości INP i innych podstawowych wskaźników internetowych, aby szybko identyfikować i rozwiązywać wszelkie problemy z wydajnością. Gdy wartość danych przekroczy określony próg (na podstawie zdefiniowanych przez Google zakresów), atrybucja jest rejestrowana, aby można było przeanalizować i rozwiązać problem.

W tym systemie do rejestrowania tych danych od prawdziwych użytkowników użyto biblioteki web-vitals. Dzięki temu dane są rejestrowane w sposób, który dokładnie odpowiada temu, jak są mierzone przez Chrome i zgłaszane do innych narzędzi Google (takich jak Raport na temat użytkowania Chrome, Page Speed Insights, Raport o szybkości w Search Console i inne).

Aby uzyskać kompleksowy widok i centralne śledzenie, firma Fotocasa używała Datadog do zbierania i wizualizowania danych, co umożliwiło zespołowi podejmowanie świadomych decyzji opartych na danych. Dzięki niestandardowym danym zachowuje on opłacalność i umożliwia śledzenie niemal wszystkich użytkowników witryny Fotocasa.

Panel Datadog firmy Fotocasa wyświetlający różne dane dotyczące wydajności, w tym INP, LCP i CLS, w czasie.
Rysunek 5. Panel Fotocasa Datadog Performance RUM.
Panel Datadog z wykresami wskaźników opóźnienia wejścia, czasu przetwarzania i opóźnienia wyświetlania.
Rysunek 6. Dane dotyczące opóźnienia wejściowego, czasu przetwarzania i opóźnienia wyświetlania.

Ten system umożliwia zespołowi Fotocase szybkie sprawdzanie, czy wprowadzone zmiany wpływają na dane, oraz czy nie występują nieprzewidziane modyfikacje, które mogą je naruszać. Wskaźnik INP można następnie podzielić na części, takie jak opóźnienie wejściowe, czas przetwarzania i opóźnienie wyświetlania, aby dokładnie określić, która część interakcji jest główną przyczyną długich czasów interakcji.

Wykres z Datadog pokazujący nagły wzrost wartości INP, co wskazuje na anomalię.
Rys. 7. W panelu wykryto anomalię dotyczącą INP.
Alarm monitora w Datadog pokazujący wykrytą anomalię INP.
Rys. 8. W alarmie monitora wykryto anomalię INP.

Po wykryciu anomalii, takich jak te przedstawione na rysunkach 7 i 8, firma Fotocasa szybko zareagowała i użyła OpenSearch, czyli innego narzędzia, które pomogło jej określić, gdzie może dochodzić do zmian. Dane dostarczone przez bibliotekę web-vitals pomogły zidentyfikować cel (element DOM, który może być odpowiedzialny za podwyższoną wartość danych) i umożliwiły zespołowi skupienie się na rozwiązaniu problemu.

Panel OpenSearch wyświetlający dane z biblioteki web-vitals, używane do identyfikowania elementów DOM, które mają wpływ na wskaźnik INP.
Rysunek 9. Panel OpenSearch do debugowania, które elementy docelowe mają wpływ na dane INP.

Możesz też zdefiniować różne filtry, np. typ strony, urządzenie lub stan wczytania, aby uprościć scenariusze i dokładniej zrozumieć, jak na INP wpływają różne czynniki.

Narzędzia dla programistów React

Narzędzia dla programistów React zostały użyte do zwiększenia możliwości debugowania w przypadku Fotocasa. Zapewniają one zaawansowaną funkcję, która pozwala wizualnie wyróżniać komponenty, które zostały ponownie wyrenderowane.

Tę funkcję można włączyć na karcie Profiler. Następnie kliknij ikonę koła zębatego po prawej stronie górnego paska, otwórz kartę Ogólne i zaznacz pole wyboru Wyróżniaj aktualizacje podczas renderowania komponentów. Po włączeniu tej opcji komponenty są wyróżniane, gdy są ponownie renderowane, co zapewnia dynamiczną wizualizację.

Panel ustawień w Narzędziach dla programistów React z zaznaczonym polem wyboru „Highlight updates when components render” (Wyróżniaj aktualizacje podczas renderowania komponentów).
Rys. 10. Konfiguracja profilera w Narzędziach dla programistów React.

Ustalanie przyczyny ponownego renderowania

Gdy zidentyfikujesz komponent, który został ponownie wyrenderowany, następne pytanie brzmi: „Dlaczego tak się stało?”. Narzędzia React DevTools wyświetlają pomocną etykietkę w widoku wykresu płomieniowego.

Aby uzyskać dostęp do tych informacji, nagraj sesję profilowania. Analizując dane wyjściowe profilera, możesz znaleźć przydatne informacje:

  • W prawym górnym rogu wyświetla się liczba commitów React.
  • Wykres płomieniowy wizualnie przedstawia drzewo komponentów, a szary kolor oznacza komponenty, które nie zostały ponownie wyrenderowane. Każdy słupek reprezentuje moment, w którym zmieniło się drzewo komponentów Reacta i w którym odpowiednia zmiana została zatwierdzona w DOM.
  • Po najechaniu kursorem na poszczególne komponenty na wykresie płomieniowym pod nagłówkiem Dlaczego nastąpiło renderowanie? pojawi się przyczyna ponownego renderowania.

Przyczyny ponownego renderowania komponentu mogą być następujące:

  • To pierwszy raz, gdy komponent został wyrenderowany.
  • Kontekst został zmieniony
  • Zmienione haki
  • Props changed
  • Zmieniono stan
  • Wyrenderowany komponent nadrzędny
Profiler w Narzędziach deweloperskich React wyświetlający wykres płomieniowy z otwartą etykietką komponentu, która wyjaśnia, że został on ponownie wyrenderowany, ponieważ „zmieniono haki”.
Rys. 11. Panel renderowania w profilerze Narzędzi dla programistów React.

Sprawdzanie czasu renderowania

Kolory na wykresie płomieniowym przekazują istotne informacje. Kolory, takie jak różne odcienie niebieskiego, wskazują, że komponent wymagał stosunkowo krótkiego czasu renderowania w porównaniu z innymi komponentami. Z kolei kolory takie jak pomarańczowy i czerwony oznaczają, że komponent wymagał więcej czasu na renderowanie.

Profiler narzędzi dla programistów Reacta przedstawiający wykres płomieniowy, na którym kolory wskazują czas renderowania. Odcienie niebieskiego oznaczają krótszy czas, a odcienie pomarańczowego i czerwonego – dłuższy.
Rys. 12. Czas renderowania widoczny w profilerze Narzędzi dla deweloperów React.

Jak zespół Fotocasa rozwiązał ten problem

Usuwanie niepotrzebnych ponownych renderowań

Ponowne renderowanie następuje za każdym razem, gdy React musi zaktualizować interfejs użytkownika o nowe dane. Zwykle pochodzi z działania użytkownika, odpowiedzi interfejsu API lub innych ważnych zdarzeń, które wymagają aktualizacji interfejsu. Każde ponowne renderowanie uruchamia JavaScript, więc zbyt wiele takich operacji naraz – zwłaszcza w przypadku dużego drzewa komponentów – może blokować wątek główny i powodować problemy z wydajnością.

Istnieją 2 rodzaje ponownego renderowania:

  • Konieczne ponowne renderowanie: gdy komponent rzeczywiście wymaga aktualizacji, ponieważ zawiera lub wykorzystuje nowe dane.
  • Niepotrzebne ponowne renderowanie: gdy komponent jest aktualizowany bez istotnych zmian, często z powodu nieefektywnego zarządzania stanem lub nieprawidłowej obsługi właściwości.

Kilka niepotrzebnych ponownych renderowań zwykle nie stanowi problemu, ponieważ React jest wystarczająco szybki, aby użytkownicy ich nie zauważyli. Jeśli jednak zdarzają się zbyt często lub w przypadku rozbudowanego drzewa komponentów, mogą pogorszyć wrażenia użytkowników i negatywnie wpłynąć na INP strony.

Tak było w przypadku zespołu Fotocasa. Okazało się, że witryna wielokrotnie renderowała się bez potrzeby. Występowały one w 2 głównych sytuacjach:

  • Podczas wczytywania strony: zwiększenie liczby długich zadań w wątku głównym i opóźnienie pierwszej interakcji, co negatywnie wpłynęło na INP strony.
  • Podczas interakcji użytkownika: wydłużenie czasu przetwarzania większości interakcji, co również wpłynęło negatywnie na INP.

Na stronie Fotocasa udało się zoptymalizować wiele niepotrzebnych ponownych renderowań. Jedną z największych optymalizacji, jakie udało się wprowadzić, była optymalizacja strony wyszukiwania. Podczas wczytywania strony nastąpiły 3 niepotrzebne ponowne renderowania. Po usunięciu tych elementów zaobserwowaliśmy te wyniki:

  • Mniejsza liczba długotrwałych zadań (patrz rysunek poniżej)
  • Krótszy łączny czas blokowania (porównaj rysunki 14 i 15)
Dwa główne zrzuty wątków z Narzędzi deweloperskich w Chrome. Na górnym zrzucie ekranu widać więcej długich zadań przed optymalizacją, a na dolnym – mniej długich zadań po usunięciu niepotrzebnych ponownych renderowań.
Rysunek 13. Migawka wątku głównego z niepotrzebnymi ponownymi renderowaniami i bez nich.
Raport wydajności Lighthouse na urządzeniach mobilnych pokazujący całkowity czas blokowania wynoszący 1080 ms, co wskazuje na problemy z wydajnością spowodowane niepotrzebnymi ponownymi renderowaniami.
Rys. 14. Raport Lighthouse dotyczący wydajności na urządzeniach mobilnych pokazujący niepotrzebne ponowne renderowania.
Raport Lighthouse dotyczący wydajności na urządzeniach mobilnych, w którym po usunięciu niepotrzebnych ponownych renderowań znacznie zmniejszył się łączny czas blokowania.
Rys. 15. Raport wydajności mobilnej Lighthouse bez niepotrzebnych ponownych renderowań.

Kolokacja stanowa

Nieprawidłowe umieszczenie stanu Reacta może spowolnić działanie aplikacji i sprawić, że interfejs użytkownika będzie wolno reagować. Gdy stan komponentu się zmieni, jego komponenty podrzędne zostaną domyślnie ponownie wyrenderowane, chyba że użyto mechanizmu ucieczki (np. memo).

Jak wyjaśniliśmy w poprzedniej sekcji, ponowne renderowanie nie jest samo w sobie złe, ale ponowne renderowanie całej strony z powodu aktualizacji określonego stanu może prowadzić do wolniejszych interakcji, ponieważ aktualizacje DOM następują po renderowaniu.

Na przykład na stronie wyszukiwania znajduje się okno, które po kliknięciu przycisku wyświetla wszystkie filtry.

Pasek filtrów na stronie wyszukiwania Fotocasa z przyciskiem otwierającym okno ze wszystkimi filtrami.
Rys. 16. Pasek filtrów Fotocasa.

Stan, który w tym przypadku kontroluje stan otwarcia okna, został umieszczony na stronie wyszukiwania. Gdy ten stan się zmieniał, cała strona była ponownie renderowana, co powodowało wysoki wskaźnik INP, zwłaszcza na wolniejszych urządzeniach, jak widać po użyciu ograniczenia procesora w Narzędziach deweloperskich:

Ograniczanie wykorzystania procesora INP
4-krotne spowolnienie 440 milisekund (wymaga poprawy)
6-krotne spowolnienie 832 milisekundy (słaba)

Zmiana stanu jak najbliżej komponentu, który wywołuje zmianę, rozwiązuje ten problem. W tym konkretnym przypadku stan można umieścić w komponencie przycisku filtrów, aby po zmianie stanu ponownie renderowany był tylko przycisk.

Ograniczanie wykorzystania procesora INP
4-krotne spowolnienie 64 milisekundy (dobrze)
6-krotne spowolnienie 232 milisekundy (wymaga poprawy)

Usuwanie niepotrzebnych stanów

Stany nie powinny zawierać zbędnych ani zduplikowanych informacji. Jeśli tak się stanie, może to prowadzić do niepotrzebnego ponownego renderowania i powodować problemy.

Na przykład na pasku filtrów Fotocasa znajduje się tekst informujący o liczbie filtrów zastosowanych w danym wyszukiwaniu:

Pasek filtrów Fotocasa z przyciskiem „Filtry” i liczbą wskazującą liczbę zastosowanych filtrów.
Rys. 17. Przycisk filtrów i licznik Fotocasa.

Liczba zastosowanych filtrów jest obliczana na podstawie stanu aplikacji. Spowodowało to jednak nie tylko niepotrzebne ponowne renderowanie całego komponentu, ale w niektórych przypadkach także przesunięcie układu, ponieważ ten komponent jest renderowany po stronie serwera:

const [filtersCount, setFiltersCount] = useState(DEFAULT_COUNTER)

useEffect(() => {
  const counter = filters
    ? Object.keys(filters)
        ?.reduce(reducerCounter, [])
        ?.filter((param) => searchParams?.[param]).length
    : DEFAULT_COUNTER

  setFiltersCount(counter)
}, [searchParams]);

Aby rozwiązać ten problem, wartość została wyprowadzona z obiektu filtrów za pomocą zmiennej zamiast stanu:

const counter = filters
    ? Object.keys(filters)
        ?.reduce(reducerCounter, [])
        ?.filter((param) => searchParams?.[param]).length
    : DEFAULT_COUNTER;

Ograniczanie kosztownych renderowań

Gdy w aplikacji React nastąpi interakcja, zwykle powoduje to zmianę stanu. Jak już wspomnieliśmy, gdy stan komponentu się zmieni, zostanie on ponownie wyrenderowany wraz ze wszystkimi komponentami podrzędnymi.

Jeśli jedna z tych funkcji renderowania komponentów działa wolno, wpłynie to negatywnie na INP strony, ponieważ prawdopodobnie zostanie wygenerowane długie zadanie, a aktualizacja DOM zajmie więcej czasu.

Zespół Fotocasa starał się jak najbardziej zminimalizować czasochłonne obliczenia w funkcji renderowania komponentów. Narzędzia deweloperskie w Chrome i Narzędzia deweloperskie React były bardzo przydatne do wykrywania powolnych operacji renderowania.

Opóźnianie wykonania kodu

Oprócz optymalizacji funkcji renderowania komponentów zoptymalizowano też inne funkcje, aby jak najbardziej zminimalizować długie zadania. Niektórych zadań nie udało się jednak zoptymalizować, ponieważ zależały od kodu innej firmy.

Przykładem są dane analityczne. W tym przypadku zdecydowano się opóźnić wykonanie kodu analitycznego i nadać priorytet aktualizacjom DOM, gdy dochodziło do interakcji użytkownika. Aby to osiągnąć, zespół Fotocasa użył biblioteki o nazwie idlefy, która zapewniała też, że kod analityczny będzie działać nawet wtedy, gdy przeglądarka zostanie natychmiast zamknięta.

Kultura wyników

Praca nad wydajnością nie jest jednorazowym wysiłkiem, ale czymś, co należy brać pod uwagę przy wdrażaniu każdej funkcji. Wszyscy członkowie zespołu muszą być zgodni, w przeciwnym razie pogorszenie podstawowych wskaźników internetowych jest niemal nieuniknione.

Aby temu zapobiec, zespół Fotocasa aktywnie dzielił się wiedzą w ramach zespołu i opracował jasne ramy identyfikowania problemów z wydajnością na podstawie danych RUM z Datadog Fotocasa, w tym sposoby ich odtwarzania. W systemie RUM skonfigurowano alerty dotyczące podstawowych wskaźników internetowych, zwłaszcza INP, które powiadamiały zespół Fotocasa bezpośrednio na Slacku. Dzięki temu wydajność była zawsze na pierwszym miejscu, a problemy można było wykrywać, zanim przerodziły się w regresję.

Wyniki

Poprawa INP w przypadku Fotocasa wymagała połączenia optymalizacji technicznych i zmian kulturowych. Dzięki wyeliminowaniu niepotrzebnych ponownych renderowań, optymalizacji umieszczania stanu, ograniczeniu kosztownych renderowań i odroczeniu niekrytycznego kodu zespół Fotocasa zdołał przenieść wszystkie strony na komputery ze stanu „wymaga poprawy” do stanu „dobry” i znacznie poprawić strony mobilne, przenosząc prawie wszystkie strony ze stanu „słaby” i „wymaga poprawy” do stanu „dobry”.

Google Search Console pokazuje podstawowe wskaźniki internetowe Fotocasa na komputery po wprowadzeniu ulepszeń dotyczących wartości INP.
Rys. 18. Google Search Console pokazuje podstawowe wskaźniki internetowe Fotocasa na komputery po wprowadzeniu ulepszeń dotyczących wartości INP.

Te zmiany poprawiły ogólne wrażenia użytkowników Fotocasa i wraz z innymi inicjatywami spowodowały wzrost liczby reklam z formularzem kontaktowym i reklam z połączeniem telefonicznym o 27%, co bezpośrednio wpłynęło na kluczowe wskaźniki biznesowe firmy.

Monitorowanie w czasie rzeczywistym za pomocą Datadog pozwoliło zespołowi Fotocasa zweryfikować poprawę INP, szybko wykrywać anomalie i zapobiegać regresjom. Oprócz tych osiągnięć firma Fotocasa zdołała też włączyć wydajność witryny do swojej kultury rozwoju, dzięki czemu INP i podstawowe wskaźniki internetowe pozostają priorytetem w każdej wersji.