Interfejs API czasu działań użytkownika

Informacje o aplikacji internetowej

Alex Danilo

Wydajne aplikacje internetowe mają kluczowe znaczenie dla wygody użytkowników. Ponieważ aplikacje internetowe stają się coraz bardziej złożone, zrozumienie wpływu na wydajność ma kluczowe znaczenie dla wygody użytkowników. W ciągu ostatnich kilku lat w przeglądarce pojawiło się wiele różnych interfejsów API ułatwiających analizowanie wydajności sieci, czasów wczytywania itd. Niekoniecznie dostarczają one szczegółowych informacji, na podstawie których można określić, co spowalnia działanie aplikacji. Wpisz interfejs User Timing API, który zapewnia mechanizm umożliwiający dostosowanie aplikacji internetowej do potrzeb użytkownika. W tym artykule omówimy interfejs API i poznamy przykłady jego zastosowania.

Nie możesz zoptymalizować tego, czego nie możesz zmierzyć

Pierwszym krokiem w przyspieszaniu powolnego działania aplikacji internetowej jest określenie, gdzie jest poświęcany czas. Pomiar wpływu obszarów kodu JavaScript na czas działania jest idealnym sposobem na identyfikowanie zagrożonych obszarów, co jest pierwszym krokiem do poprawy skuteczności. Na szczęście interfejs User Timing API umożliwia wstawianie wywołań interfejsu API w różnych częściach kodu JavaScript i pobieranie szczegółowych danych o czasie, które mogą pomóc w optymalizacji.

Czas w wysokiej rozdzielczości i now()

Najważniejszym elementem dokładnego pomiaru czasu jest precyzja. W dawnych czasach mierzono czas na pomiarze rzędu około milisekund, co było dopuszczalne, ale stworzenie witryny z szybkością 60 FPS oznaczało, że każda klatka musi być rysowana w czasie 16 ms. Tak więc przy dokładności rzędu kilku milisekund brakuje dokładności potrzebnej do przeprowadzenia dobrej analizy. Wpisz Czas w wysokiej rozdzielczości, nowy typ czasu wbudowanego w nowoczesne przeglądarki. Czas w wysokiej rozdzielczości to znaczniki czasu zmiennoprzecinkowe, które mogą być precyzyjne z dokładnością do mikrosekundy, czyli tysiąc razy lepsze niż wcześniej.

Aby sprawdzić aktualną godzinę w aplikacji internetowej, wywołaj metodę now(), która stanowi rozszerzenie interfejsu Wydajność. Poniższy kod pokazuje, jak to zrobić:

var myTime = window.performance.now();

Istnieje też inny interfejs o nazwie PerformanceTiming, który pokazuje różne czasy związane z wczytywaniem aplikacji internetowej. Metoda now() zwraca czas, który upłynął od wystąpienia zdarzenia navigationStart w parametrze PerformanceTiming.

Typ DOMHighResTimeStamp

W przeszłości próbując sprawdzić czas aplikacji internetowych, należało użyć funkcji w rodzaju Date.now(), która zwraca wartość DOMTimeStamp. DOMTimeStamp zwraca jako wartość liczbę całkowitą wyrażoną w milisekundach. Aby zapewnić większą dokładność (w wysokiej rozdzielczości) na potrzeby czasu wysokiej rozdzielczości, wprowadziliśmy nowy typ o nazwie DOMHighResTimeStamp. Ten typ jest wartością zmiennoprzecinkową, która również zwraca czas w milisekundach. Jest to jednak liczba zmiennoprzecinkowa, więc wartość może być ułamkowa (milisekundy), więc dokładność może wynosić nawet 1000 milisekundy.

Interfejs czasu użytkownika

Teraz, gdy mamy już sygnatury czasowe o wysokiej rozdzielczości, użyjmy interfejsu Czas użytkownika, aby pobrać informacje o czasie.

Interfejs User Timing zawiera funkcje, które pozwalają nam wywoływać metody w różnych miejscach w aplikacji. Generują one ścieżkę menu nawigacyjnego w stylu Hansela i Gretel, co pozwala nam śledzić, gdzie jest dany czas.

Jak korzystać z aplikacji mark()

Metoda mark() jest głównym narzędziem w naszym zestawie narzędzi do analizy czasu. mark() przechowuje dla nas sygnaturę czasową. Bardzo przydatną funkcją mark() jest możliwość nazwania sygnatury czasowej, a interfejs API zapamięta ją jako pojedynczą jednostkę.

Możesz zadzwonić pod numer mark() w różnych miejscach w aplikacji, aby sprawdzić, ile czasu zajęło Ci kliknięcie tego „znaku” w aplikacji.

Specyfikacja zawiera szereg sugerowanych nazw znaków, które mogą być interesujące i nie wymagają wyjaśnień, np. mark_fully_loaded,mark_fully_visible, mark_above_the_fold itp.

Za pomocą tego kodu można na przykład określić czas pełnego wczytania aplikacji:

window.performance.mark('mark_fully_loaded');

Ustawiając nazwane znaczniki w naszej aplikacji internetowej, możemy gromadzić mnóstwo danych dotyczących czasu i analizować je w dowolnym momencie, aby określić, co i kiedy robi aplikacja.

Obliczanie pomiarów za pomocą funkcji measure()

Gdy ustawisz kilka znaczników czasu, sprawdź, ile czasu upływa między nimi. Aby to zrobić, użyj metody measure().

Metoda measure() oblicza czas, który upływa między znacznikami, a także może mierzyć czas między oznaczeniem a dowolnymi znanymi nazwami zdarzeń w interfejsie PerformanceTiming.

Korzystając z takiego kodu, możesz np. ustalić, ile czasu upływa od ukończenia modelu DOM do pełnego wczytania stanu aplikacji:

window.performance.measure('measure_load_from_dom', 'domComplete', 'mark_fully_loaded');

Wywołanie funkcji measure() zapisuje wynik niezależnie od ustawionych przez Ciebie znaków, dzięki czemu możesz je później pobrać. Dzięki przechowywaniu czasów nieobecności w trakcie działania aplikacji aplikacja pozostaje responsywna i po zakończeniu pracy można zrzucać wszystkie dane, aby można je było później przeanalizować.

Odrzucanie znaczników za pomocą funkcji clearMarks()

Czasami przydatna jest możliwość usunięcia kilku zapisanych śladów. Możesz na przykład uruchomić wsadowe uruchamianie swojej aplikacji internetowej, więc chcesz zawsze uruchamiać je od nowa.

Wystarczy zadzwonić pod numer clearMarks(), aby usunąć wszelkie skonfigurowane oznaczenia.

Przykładowy kod poniżej usunie wszystkie istniejące znaczniki, dzięki czemu w razie potrzeby możesz ponownie skonfigurować uruchomienie czasowe.

window.performance.clearMarks();

Oczywiście w niektórych sytuacjach możesz nie chcieć usunąć wszystkich oznaczeń. Jeśli chcesz pozbyć się określonych śladów, możesz przekazać ich nazwę. Na przykład ten kod:

window.peformance.clearMarks('mark_fully_loaded');

usuwa znak ustawiony w pierwszym przykładzie, a wszystkie pozostałe oznaczenia pozostaje bez zmian.

Możesz też pozbyć się wszystkich wykonanych pomiarów. Istnieje do tego odpowiednia metoda o nazwie clearMeasures(). Działa dokładnie tak samo jak clearMarks(), ale działa na podstawie wszystkich wykonanych przez Ciebie pomiarów. Na przykład kod:

window.performance.clearMeasures('measure_load_from_dom');

spowoduje usunięcie wskaźnika zastosowanego w powyższym przykładzie (measure()). Jeśli chcesz usunąć wszystkie wskaźniki, działa to tak samo jak funkcja clearMarks() – musisz wywołać funkcję clearMeasures() bez argumentów.

Pobieram dane o czasie

Dobrze jest ustawić znaczniki i mierzyć interwały, ale w pewnym momencie chcesz uzyskać dane o tym czasie, aby przeprowadzić analizę. To naprawdę proste. Wystarczy, że użyjesz interfejsu PerformanceTimeline.

Na przykład metoda getEntriesByType() pozwala nam pobrać z listy wszystkie czasy znacznika lub czasu oczekiwania na wyniki wszystkich pomiarów, co pozwoli nam na powtórzenie i przeanalizowanie danych. Lista jest zwracana w porządku chronologicznym, dzięki czemu możesz zobaczyć znaki w kolejności, w jakiej zostały one trafione w Twojej aplikacji internetowej.

Ten kod:

var items = window.performance.getEntriesByType('mark');

zwraca listę wszystkich znaków napotkanych w naszej aplikacji internetowej, a kod:

var items = window.performance.getEntriesByType('measure');

zwraca listę wszystkich podjętych przez nas działań.

Możesz też wrócić do listy wpisów, używając nadanej im konkretnej nazwy. Na przykład kod:

var items = window.performance.getEntriesByName('mark_fully_loaded');

zwróci listę zawierającą jeden element zawierający znacznik czasu „mark_full_loaded” we właściwości startTime.

Czas realizacji żądania XHR (przykład)

Teraz, gdy mamy już całkiem niezły obraz interfejsu User Timing API, możemy użyć go do analizy czasu, przez jaki XMLHttpRequests pojawiają się w naszej aplikacji internetowej.

Najpierw zmodyfikujemy wszystkie żądania send(), aby wykonać wywołanie funkcji, które konfiguruje znaczniki, i jednocześnie zmienimy nasze udane wywołania zwrotne za pomocą wywołania funkcji, która ustawia kolejny znak, a następnie generuje pomiar czasu trwania żądania.

Normalnie żądanie XMLHttpRequest wyglądałoby mniej więcej tak:

var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
  do_something(e.responseText);
}
myReq.send();

W naszym przykładzie dodamy globalny licznik, który będzie śledził liczbę żądań i będzie go używać do przechowywania wskaźników dla każdego przesłanego żądania. Odpowiedni kod wygląda tak:

var reqCnt = 0;

var myReq = new XMLHttpRequest();
myReq.open('GET', url, true);
myReq.onload = function(e) {
  window.performance.mark('mark_end_xhr');
  reqCnt++;
  window.performance.measure('measure_xhr_' + reqCnt, 'mark_start_xhr', 'mark_end_xhr');
  do_something(e.responseText);
}
window.performance.mark('mark_start_xhr');
myReq.send();

Powyższy kod generuje wskaźnik z niepowtarzalną wartością nazwy dla każdego wysyłanego przez nas żądania XMLHttpRequest. Zakładamy, że żądania są uruchamiane w kolejności – kod żądań równoległych musiałby być nieco bardziej złożony, aby obsługiwać żądania zwracane w złej kolejności. Zostawimy to dla czytnika jako ćwiczenie.

Gdy aplikacja internetowa wykona kilka żądań, zrzucamy je wszystkie do konsoli przy użyciu tego kodu:

var items = window.performance.getEntriesByType('measure');
for (var i = 0; i < items.length; ++i) {
  var req = items[i];
  console.log('XHR ' + req.name + ' took ' + req.duration + 'ms');
}

Podsumowanie

Interfejs User Timing API udostępnia wiele przydatnych narzędzi do zastosowania do dowolnego aspektu aplikacji internetowej. Aby ograniczyć obszary aktywne w aplikacji, wystarczy rozsunąć w niej wywołania interfejsu API i przetworzyć wygenerowane dane o czasie w celu uzyskania wyraźnego obrazu tego, w jaki sposób spędzany czas. Ale co, jeśli Twoja przeglądarka nie obsługuje tego interfejsu API? Nie ma sprawy. Tutaj znajdziesz świetny kod polyfill, który naprawdę dobrze emuluje interfejs API i działa dobrze z webpagetest.org. Nie ma na co czekać. Już teraz wypróbuj interfejs User Timing API w swoich aplikacjach. Dowiedz się, jak je przyspieszyć, a użytkownicy podziękują Ci za to, że korzystanie z nich jest tak lepsze.