Dowiedz się, czym jest opóźnienie sygnału wejściowego, i poznaj techniki jego redukcji, aby zwiększyć interaktywność.
Interakcje w internecie to złożone rzeczy, a każda aktywność w przeglądarce musi ich prowadzić. Łączy je jednak to, że następują pewne opóźnienia przed rozpoczęciem wywołań zwrotnych zdarzeń. Z tego przewodnika dowiesz się, czym jest opóźnienie wprowadzania danych i jak je zminimalizować, aby interakcje ze stroną działały szybciej.
Co to jest opóźnienie danych wejściowych?
Opóźnienie wejścia to czas od pierwszej interakcji użytkownika ze stroną – np. dotknięcia ekranu, kliknięcia myszą lub naciśnięcia klawisza – do momentu rozpoczęcia wywołania zwrotnego tej interakcji. Każda interakcja zaczyna się z pewnym opóźnieniem w związku z przesyłaniem danych.
Pewnej części opóźnienia wprowadzania danych jest nieuniknione. System operacyjny potrzebuje trochę czasu, by rozpoznać zdarzenie wejściowe i przekazać je do przeglądarki. Jednak taka część opóźnienia wprowadzania danych jest często niezauważalna, a na stronie dzieją się też inne czynniki, które mogą powodować opóźnienia na tyle długie, że powodują problemy.
Co zrobić z opóźnieniem wprowadzania danych
Zasadniczo każda część interakcji powinna być jak najkrótsza, aby witryna miała jak największe szanse na osiągnięcie progu „dobrej” interakcji z interakcją do następnego wyrenderowania (INP), niezależnie od urządzenia użytkownika. Kontrolowanie opóźnienia danych wejściowych to tylko jeden z elementów osiągnięcia tego progu.
Dlatego należy dążyć do jak najkrótszego możliwego opóźnienia wejścia, aby osiągnąć próg „dobrej” wartości INP. Musisz jednak pamiętać, że nie można całkowicie wyeliminować opóźnień w przesyłaniu danych. Jeśli unikasz nadmiernej pracy w wątku głównym, gdy użytkownicy próbują korzystać z Twojej strony, opóźnienie wprowadzania powinno być na tyle małe, aby uniknąć problemów.
Jak zminimalizować opóźnienie sygnału
Jak wspomnieliśmy wcześniej, pewne opóźnienia wejściowe są nieuniknione, ale z drugiej strony można ich uniknąć. Oto kilka kwestii, które warto wziąć pod uwagę, jeśli zmagasz się z długimi opóźnieniami w przesyłaniu danych.
Unikaj powtarzających się minutników, które uruchamiają nadmierną pracę w wątku głównym
W JavaScripcie są 2 powszechnie używane funkcje licznika czasu, które mogą wpływać na opóźnienie danych wejściowych: setTimeout
i setInterval
. Różnica między nimi polega na tym, że setTimeout
planuje wykonanie wywołania zwrotnego po określonym czasie. setInterval
z kolei planuje wykonanie wywołania zwrotnego co n milisekund lub do momentu zatrzymania licznika za pomocą przycisku clearInterval
.
Usługa setTimeout
sama w sobie nie stanowi problemu, ale może być pomocna, aby unikać długich zadań. Zależy to jednak od czasu przekroczenia limitu czasu oraz od tego, czy użytkownik spróbuje wejść w interakcję ze stroną po upływie limitu czasu oczekiwania.
Dodatkowo setTimeout
może być uruchamiany w pętli lub rekurencyjnie, gdzie działa bardziej jak setInterval
. Lepiej jednak nie planować następnej iteracji do czasu zakończenia poprzedniej. Oznacza to, że pętla jest przekazywana w wątku głównym przy każdym wywołaniu funkcji setTimeout
, jednak należy zadbać o to, aby wywołanie zwrotne nie zakończyło się zbyt dużą pracą.
Funkcja setInterval
uruchamia wywołanie zwrotne w określonym przedziale czasu, dlatego jest znacznie bardziej prawdopodobne, że przeszkadza w interakcjach. Dzieje się tak, ponieważ w przeciwieństwie do pojedynczego wystąpienia wywołania setTimeout
, które jest jednorazowym wywołaniem zwrotnym, które może przeszkodzić w interakcji użytkownika, cykliczny charakter setInterval
sprawia, że znacznie zwiększa prawdopodobieństwo, że przeszka ono w interakcji, co zwiększy opóźnienie interakcji.
Jeśli liczniki czasu działają w kodzie własnym, masz nad nimi kontrolę. Zastanów się, czy są Ci one potrzebne, czy też postaraj się je maksymalnie ograniczyć. Liczniki czasu w scenariuszach zewnętrznych to jednak coś innego. Często nie masz kontroli nad działaniem zewnętrznego skryptu, a rozwiązywanie problemów z wydajnością kodu zewnętrznego wymaga współpracy z zainteresowanymi osobami w celu określenia, czy dany skrypt zewnętrzny jest potrzebny. Jeśli tak, skontaktuj się z tym dostawcą, aby dowiedzieć się, jak rozwiązać problemy z wydajnością, jakie mogą powodować w witrynie.
Unikanie długich zadań
Jednym ze sposobów na ograniczenie długich opóźnień przy wprowadzaniu danych jest unikanie długich zadań. Jeśli nadmierna ilość pracy z wątku głównego blokuje ten wątek podczas interakcji, wydłuża się opóźnienie wprowadzania danych przed zakończeniem długich zadań.
Poza ograniczeniem ilości pracy wykonywanej w danym zadaniu i zawsze staraj się wykonywać jak najmniejszą ilość pracy w wątku głównym – możesz też poprawić reakcję na działania użytkownika przez podzielenie długich zadań.
Zwróć uwagę na pokrywanie się interakcji
Szczególnie trudne w optymalizacji INP może być sytuacja, w której interakcje się pokrywają. Nakładanie się interakcji oznacza, że po interakcji z jednym elementem rozpoczynasz kolejną interakcję ze stroną, zanim pierwsza interakcja miała szansę wyrenderować następną klatkę.
Źródła interakcji mogą być tak proste, jak użytkownicy wykonujący wiele interakcji w krótkim czasie. Może się tak zdarzyć, gdy użytkownicy wpisują pola formularza, czyli w krótkim czasie może dojść do wielu interakcji z klawiaturą. Jeśli praca nad kluczowym zdarzeniem jest szczególnie kosztowna – na przykład w przypadku pól autouzupełniania, w których żądania sieciowe są wysyłane do backendu, masz 2 możliwości:
- Rozważ odrzucanie danych wejściowych, aby ograniczyć liczbę wywołań zwrotnych zdarzenia w danym okresie.
- Użyj funkcji
AbortController
, aby anulować wychodzące żądaniafetch
, aby wątek główny nie przeciążył się podczas obsługi wywołań zwrotnychfetch
. Uwaga: właściwościsignal
instancjiAbortController
może też służyć do przerywania zdarzeń.
Innym źródłem zwiększonego opóźnienia danych wejściowych z powodu nakładających się interakcji mogą być kosztowne animacje. Animacje w języku JavaScript mogą w szczególności powodować uruchamianie wielu wywołań requestAnimationFrame
, które mogą zakłócać interakcje użytkowników. Aby obejść ten problem, w miarę możliwości używaj animacji CSS. Pozwoli to uniknąć umieszczania w kolejce potencjalnie kosztownych klatek animacji. Jeśli to zrobisz, unikaj nieskomponowanych animacji, aby działały one głównie w wątkach GPU i kompozytora, a nie w wątku głównym.
Podsumowanie
Opóźnienia danych wejściowych mogą nie odpowiadać większości czasu potrzebnego na przeprowadzenie interakcji, ale pamiętaj, że każda jej część zajmuje dużo czasu, który możesz skrócić. Jeśli obserwujesz duże opóźnienie wprowadzania danych, masz szansę je zmniejszyć. Unikanie powtarzających się wywołań zwrotnych licznika czasu, dzielenie długich zadań i świadomość o potencjalnym nakładaniu się interakcji może pomóc zmniejszyć opóźnienie wprowadzania danych i przyspieszyć interakcję użytkowników witryny.
Baner powitalny z albumu Unsplash, autorstwa Erika Mcleana.