Pomiar wydajności za pomocą taktowania serwera

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ Nagłówek Server Timing zapewnia dyskretny i wygodny sposób przekazywania informacji o czasie działania serwera zaplecza narzędziom programistycznym w przeglądarce. Dodanie informacji o taktowaniu do aplikacji umożliwia monitorowanie wydajności zaplecza i frontonu w jednym miejscu.

Podejmując jakąkolwiek pracę nad optymalizacją wydajności, jedną z pierwszych rzeczy, których się uczymy, jest to, że zanim będziesz mógł poprawić wydajność, musisz ją najpierw zmierzyć. Bez możliwości zmierzenia szybkości, z jaką coś działa, nie możemy stwierdzić, czy wprowadzane zmiany poprawiają wydajność, nie przynoszą żadnego efektu, a nawet pogarszają sytuację.

Wielu z nas na pewnym poziomie będzie zaznajomionych z pracą nad problemem wydajnościowym. Może to być coś tak prostego, jak próba ustalenia, dlaczego JavaScript na Twojej stronie nie uruchamia się wystarczająco szybko lub dlaczego wyświetlanie obrazów w złym hotelowym Wi-Fi trwa zbyt długo. Odpowiedzi na tego rodzaju pytania często można znaleźć w bardzo znajomym miejscu: narzędziach programistycznych przeglądarki.

Przez lata ulepszaliśmy narzędzia programistyczne, aby pomóc nam rozwiązywać tego rodzaju problemy z wydajnością w interfejsie naszych aplikacji. Przeglądarki mają teraz nawet wbudowane audyty wydajności. Może to pomóc w śledzeniu problemów z interfejsem, ale te audyty mogą ujawnić inne źródło spowolnienia, którego nie możemy naprawić w przeglądarce. Problemem są powolne czasy odpowiedzi serwera.

„Czas do pierwszego bajtu”

Bardzo niewiele optymalizacji przeglądarki może zrobić, aby ulepszyć stronę, która po prostu wolno się buduje na serwerze. Koszt ten jest ponoszony między przeglądarką wysyłającą żądanie o plik a otrzymaniem odpowiedzi. Analiza wykresu kaskadowego sieci w narzędziach programistycznych pokaże to opóźnienie w kategorii „Oczekiwanie (TTFB)”. Tyle czasu przeglądarka czeka między wysłaniem żądania a otrzymaniem odpowiedzi.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Pod względem wydajności jest to znane jako czas do pierwszego bajtu – czas, jaki zajmuje serwerowi wysyłanie czegoś, z czym przeglądarka może zacząć pracować. W tym czasie oczekiwania znajduje się wszystko, co serwer musi zrobić, aby zbudować stronę. W typowej witrynie może to obejmować kierowanie żądania do odpowiedniej części aplikacji, uwierzytelnianie żądania, wykonywanie wielu wywołań do systemów zaplecza, takich jak bazy danych i tak dalej. Może to obejmować uruchamianie treści przez systemy szablonów, wykonywanie wywołań API do usług stron trzecich, a może nawet wysyłanie wiadomości e-mail lub zmianę rozmiaru obrazów. Każda praca wykonywana przez serwer w celu zakończenia żądania jest zgnieciona w tym oczekiwaniu TTFB, którego użytkownik doświadcza w swojej przeglądarce.

Panel Sieć w Chrome DevTools pokazujący kontrolę pojedynczego żądania strony
Sprawdzanie żądania dokumentu pokazuje czas, jaki przeglądarka spędza na oczekiwaniu na odpowiedź z serwera.

Jak więc skrócić ten czas i szybciej zacząć dostarczać stronę do użytkownika? Cóż, to duże pytanie, a odpowiedź zależy od twojej aplikacji. To jest sama praca nad optymalizacją wydajności. To, co musimy najpierw zrobić, to zmierzyć wydajność, aby można było ocenić korzyści ze zmian.

Nagłówek czasu serwera

Zadaniem Server Timing nie jest pomoc w czasie aktywności na serwerze. Będziesz musiał sam ustalić czas, korzystając z dowolnego zestawu narzędzi, który udostępnia Ci platforma zaplecza. Celem synchronizacji serwera jest raczej określenie, w jaki sposób te pomiary mogą być przekazywane do przeglądarki.

Sposób, w jaki to się robi, jest bardzo prosty, przejrzysty dla użytkownika i ma minimalny wpływ na wagę Twojej strony. Informacje są wysyłane jako prosty zestaw nagłówków odpowiedzi HTTP.

 Server-Timing: db;dur=123, tmpl;dur=56

Ten przykład komunikuje dwa różne punkty czasowe o nazwach db i tmpl . Nie są one częścią specyfikacji — są to nazwy, które wybraliśmy, w tym przypadku, aby reprezentować odpowiednio czasy bazy danych i szablonów.

Właściwość dur podaje liczbę milisekund potrzebnych do zakończenia operacji. Jeśli spojrzymy na żądanie w sekcji Sieć w Narzędziach dla programistów, zobaczymy, że czasy zostały dodane do wykresu.

Panel czasów żądania strony w Chrome DevTools z nową sekcją czasu serwera.
Pojawi się nowa sekcja czasu serwera, pokazująca czasy ustawione za pomocą nagłówka HTTP Server-Timing.

Nagłówek Server-Timing może przyjmować wiele metryk oddzielonych przecinkami:

 Server-Timing: metric, metric, metric

Każda metryka może określać trzy możliwe właściwości

  1. Krótka nazwa metryki (taka jak db w naszym przykładzie)
  2. Czas trwania w milisekundach (wyrażony jako dur=123 )
  3. Opis (wyrażony jako desc="My Description" )

Każda właściwość jest oddzielona średnikiem jako ogranicznikiem. Do naszego przykładu moglibyśmy dodać opisy w następujący sposób:

 Server-Timing: db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing"
Panel Czasy żądania strony w Chrome DevTools, zawierający opisy używane do danych dotyczących czasu serwera.
Po podaniu nazwy są zastępowane opisami.

Jedyną wymaganą właściwością jest name . Zarówno dur , jak i desc są opcjonalne i mogą być używane opcjonalnie w razie potrzeby. Na przykład, jeśli trzeba debugować problem z synchronizacją, który miał miejsce na jednym serwerze lub centrum danych, a nie na innym, przydatne może być dodanie tych informacji do odpowiedzi bez skojarzonego z nimi czasu.

 Server-Timing: datacenter;desc="East coast data center", db;dur=123;desc="Database", tmpl;dur=56;desc="Template processing”

Pojawiłoby się to wtedy wraz z harmonogramami.

Panel czasów żądania strony w Chrome DevTools pokazujący czas serwera bez ustawionego czasu.
Wyświetlana jest wartość „Centrum danych Wschodniego Wybrzeża”, mimo że nie ma żadnych czasów.

Jedną z rzeczy, które możesz zauważyć, jest to, że paski czasu nie są wyświetlane we wzorze kaskadowym. Dzieje się tak po prostu dlatego, że Server Timing nie próbuje komunikować sekwencji taktowania, tylko same surowe metryki.

Wdrażanie taktowania serwera

Dokładna implementacja we własnej aplikacji będzie zależeć od konkretnych okoliczności, ale zasady są takie same. Kroki zawsze będą następujące:

  1. Czas na niektóre operacje
  2. Zbierz razem wyniki pomiaru czasu
  3. Wyprowadź nagłówek HTTP

W pseudokodzie generowanie odpowiedzi może wyglądać tak:

 startTimer('db') getInfoFromDatabase() stopTimer('db') startTimer('geo') geolocatePostalAddressWithAPI('10 Downing Street, London, UK') endTimer('geo') outputHeader('Server-Timing', getTimerOutput())

Podstawy implementacji czegoś podobnego powinny być proste w każdym języku. Bardzo prosta implementacja PHP może używać funkcji microtime() do operacji pomiaru czasu i może wyglądać podobnie do poniższych.

 class Timers { private $timers = []; public function startTimer($name, $description = null) { $this->timers[$name] = [ 'start' => microtime(true), 'desc' => $description, ]; } public function endTimer($name) { $this->timers[$name]['end'] = microtime(true); } public function getTimers() { $metrics = []; if (count($this->timers)) { foreach($this->timers as $name => $timer) { $timeTaken = ($timer['end'] - $timer['start']) * 1000; $output = sprintf('%s;dur=%f', $name, $timeTaken); if ($timer['desc'] != null) { $output .= sprintf(';desc="%s"', addslashes($timer['desc'])); } $metrics[] = $output; } } return implode($metrics, ', '); } }

Skrypt testowy używałby go w sposób przedstawiony poniżej, tutaj używając funkcji usleep() do sztucznego tworzenia opóźnienia w działaniu skryptu, aby zasymulować proces, którego ukończenie wymaga czasu.

 $Timers = new Timers(); $Timers->startTimer('db'); usleep('200000'); $Timers->endTimer('db'); $Timers->startTimer('tpl', 'Templating'); usleep('300000'); $Timers->endTimer('tpl'); $Timers->startTimer('geo', 'Geocoding'); usleep('400000'); $Timers->endTimer('geo'); header('Server-Timing: '.$Timers->getTimers());

Uruchomienie tego kodu wygenerowało nagłówek, który wyglądał tak:

 Server-Timing: db;dur=201.098919, tpl;dur=301.271915;desc="Templating", geo;dur=404.520988;desc="Geocoding"
Panel Czasy żądania strony w Chrome DevTools pokazujący prawidłowo wyświetlane wartości testowe.
Czasy serwera ustawione w przykładzie pojawiają się w panelu Timings z opóźnieniami skonfigurowanymi w naszym skrypcie testowym.

Istniejące wdrożenia

Biorąc pod uwagę, jak przydatne jest taktowanie serwera, istnieje stosunkowo niewiele implementacji, które mogłem znaleźć. Pakiet NPM synchronizacji czasu serwera oferuje wygodny sposób korzystania z synchronizacji serwera z projektów węzłów.

Jeśli używasz frameworka PHP opartego na oprogramowaniu pośredniczącym, tuupola/server-timing-middleware również zapewnia przydatną opcję. Używam tego w produkcji na Notist od kilku miesięcy i zawsze zostawiam włączone kilka podstawowych czasów, jeśli chcesz zobaczyć przykład na wolności.

Jeśli chodzi o obsługę przeglądarek, najlepsze, jakie widziałem, to Chrome DevTools i to właśnie wykorzystałem do zrzutów ekranu w tym artykule.

Rozważania

Sam czas serwera bardzo minimalizuje obciążenie odpowiedzi HTTP wysyłanej z powrotem przez sieć. Nagłówek jest bardzo minimalny i ogólnie można go bezpiecznie wysyłać, nie martwiąc się o kierowanie tylko do użytkowników wewnętrznych. Mimo to warto zachować krótkie nazwy i opisy, aby nie dodawać niepotrzebnych kosztów.

Bardziej niepokojąca jest dodatkowa praca, którą możesz wykonywać na serwerze, aby zmierzyć czas swojej strony lub aplikacji. Dodanie dodatkowego czasu i rejestrowania może samo w sobie mieć wpływ na wydajność, więc warto zaimplementować sposób włączania i wyłączania tego, gdy jest to wymagane.

Używanie nagłówka czasu serwera to świetny sposób na upewnienie się, że wszystkie informacje o taktowaniu zarówno z frontonu, jak i zaplecza aplikacji są dostępne w jednym miejscu. Zakładając, że Twoja aplikacja nie jest zbyt złożona, jej wdrożenie może być łatwe i możesz zacząć działać w bardzo krótkim czasie.

Jeśli chcesz przeczytać więcej o taktowaniu serwera, możesz wypróbować następujące rozwiązania:

  • Specyfikacja taktowania serwera W3C
  • Strona MDN dotycząca synchronizacji serwera zawiera przykłady i aktualne informacje o obsłudze przeglądarek
  • Interesujący komentarz zespołu BBC iPlayer na temat korzystania z funkcji Server Timing.