Platformy internetowe takie jak Angular, React, Vue i Svelte ułatwiają pisanie i obsługę złożonych aplikacji internetowych na dużą skalę.
Frameworki te wprowadzają jednak warstwę abstrakcji ponad modelem aplikacji przeglądarki. Kod napisany przez deweloperów przy użyciu tych abstrakcji jest zwykle transpilowany do nieczytelnego, zminimalizowanego i spakowanego kodu. W rezultacie pełne wykorzystanie możliwości Narzędzi deweloperskich do debugowania i profilowania tych aplikacji może być dla deweloperów trudne.
Jeśli na przykład profilujesz aplikację Angular za pomocą panelu Wydajność w Narzędziach deweloperskich, zobaczysz taki widok:

W takim przypadku trudno jest określić, które elementy kodu powodują problemy z wydajnością. Brakuje w nim kontekstu konstrukcji frameworka, a większość wyświetlanych informacji jest podana w postaci zminimalizowanego kodu. Trudno też odróżnić aktywność bezpośrednio związaną z napisanym przez Ciebie kodem, wewnętrznymi elementami frameworka i innym kodem zewnętrznym, który może być uruchomiony na tej samej stronie.
Częstym powodem tworzenia frameworków i abstrakcji jest implementowanie własnych rozszerzeń Narzędzi deweloperskich, które prezentują dane profilowania w kontekście koncepcji frameworka. Te narzędzia są bardzo przydatne podczas debugowania i profilowania aplikacji utworzonych za pomocą konkretnego frameworka. Często jednak musisz skorelować dane z frameworka w jego własnym profilerze z informacjami o środowisku wykonawczym przeglądarki w panelu Wydajność w Narzędziach deweloperskich. Gdy te 2 źródła danych są prezentowane oddzielnie w niezależnych narzędziach, trudno jest wykrywać i usuwać wąskie gardła, zwłaszcza gdy aplikacja staje się bardziej złożona. Oto przykład wizualizacji profilu w profilerze Narzędzi deweloperskich Angular:

W idealnym świecie deweloperzy mieliby widok, w którym oba źródła danych są wyświetlane razem w tym samym kontekście i odnoszą się do tej samej osi czasu.
Dlatego nawiązaliśmy współpracę z zespołem Angular, aby przenieść dane środowiska wykonawczego Angular bezpośrednio do panelu Wydajność za pomocą interfejsu API rozszerzalności panelu Wydajność. W tym poście przyjrzymy się możliwościom interfejsu API i sposobowi, w jaki został on wykorzystany w frameworku Angular. To wdrożenie może służyć jako przykład dla innych platform i abstrakcji, które chcą poprawić komfort pracy deweloperów, instrumentując własne narzędzia i pomagając deweloperom korzystającym z Narzędzi deweloperskich w Chrome.
Czym jest interfejs API rozszerzalności panelu wydajności?
Interfejs API umożliwia dodawanie własnych wpisów dotyczących czasu do śladu panelu Wydajność w tej samej osi czasu co pozostałe dane przeglądarki. Możesz to zrobić na 2 sposoby:
- User Timing API
- Interfejs API
console.timeStamp
User Timing API
Możesz użyć znaków performance.mark
i performance.measure
, aby dodać wpisy w ten sposób:
// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();
// ... later in your code
performance.measure("Component rendering", {
start: renderStart,
detail: {
devtools: {
dataType: "track-entry",
track: "Components",
color: "secondary",
properties: [
["Render reason", "Props changed"],
["Priority", "low"]
],
}
}
});
Spowoduje to dodanie do osi czasu ścieżki Komponenty z pomiarem:

Ten interfejs API umożliwia dodawanie wpisów do bufora osi czasu wydajności, a także wyświetlanie ich w interfejsie panelu Wydajność w Narzędziach deweloperskich.
Więcej informacji o tym interfejsie API i obiekcie devtools
znajdziesz w dokumentacji.
Interfejs API console.timeStamp
Ten interfejs API jest uproszczoną alternatywą dla interfejsu User Timing API. W tym samym przykładzie co wcześniej możesz mieć:
// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();
// ... later in your code
console.timeStamp(
"Component rendering",
/* start time */ renderStart,
/* end time (current time) */ undefined,
/* track name */ "Components",
/* track group name */ undefined,
/* color */ "secondary"
);
Ten interfejs API zapewnia wydajną metodę instrumentacji aplikacji: w przeciwieństwie do alternatywnego interfejsu User Timing API nie tworzy danych buforowanych. Ten interfejs API dodaje dane wyłącznie do panelu **Wydajność** w Narzędziach deweloperskich. Oznacza to, że gdy Narzędzia deweloperskie nie rejestrują śladu, wywołania interfejsu API nie wykonują żadnych działań, co znacznie przyspiesza ich działanie i sprawia, że są odpowiednie w przypadku ścieżek krytycznych, w których wydajność ma kluczowe znaczenie. Użycie argumentów pozycyjnych zamiast obiektu zawierającego wszystkie parametry dostosowywania ma też na celu utrzymanie jak najmniejszego rozmiaru interfejsu API.
Więcej informacji o używaniu console.timeStamp do rozszerzania panelu Skuteczność i o parametrach, które możesz przekazywać, znajdziesz w dokumentacji.
Jak Angular zintegrował interfejs API rozszerzalności Narzędzi deweloperskich
Przyjrzymy się, jak zespół Angulara wykorzystał interfejs API rozszerzalności do integracji z Narzędziami deweloperskimi w Chrome.
Unikaj narzutu związanego z funkcją console.timestamp
Instrumentacja Angulara za pomocą interfejsu API rozszerzalności panelu Wydajność jest dostępna od wersji 20. Wymagany poziom szczegółowości danych o wydajności w Narzędziach deweloperskich wymaga szybkiego interfejsu API, więc w żądaniu pull (60217), które dodało instrumentację, wybrano interfejs API console.timeStamp
. Zapobiega to wpływowi potencjalnego obciążenia interfejsu API profilowania na wydajność środowiska wykonawczego aplikacji.
Dane z instrumentów
Aby uzyskać dobry obraz tego, jaki kod Angulara jest uruchamiany i dlaczego, instrumentujemy wiele części potoków uruchamiania i renderowania, w tym:
- Uruchamianie aplikacji i komponentów.
- tworzenie i aktualizowanie komponentów;
- Wykonywanie detektorów zdarzeń i punktów zaczepienia cyklu życia.
- Wiele innych (np. dynamiczne tworzenie komponentów i odraczanie renderowania bloków).
Kodowanie kolorami
Kodowanie kolorami służy do informowania dewelopera o kategorii, do której należy dany wpis pomiaru. Na przykład kolory używane w przypadku wpisów oznaczających wykonanie kodu TypeScript napisanego przez dewelopera różnią się od kolorów używanych w przypadku kodu wygenerowanego przez kompilator Angular.
Na zrzucie ekranu poniżej widać, jak punkty wejścia (takie jak wykrywanie zmian i przetwarzanie komponentów) są oznaczone na niebiesko, wygenerowany kod na fioletowo, a kod TypeScript (np. odbiorniki zdarzeń i haki) na zielono.

Pamiętaj, że argument koloru przekazywany do interfejsu API nie jest wartością koloru CSS, ale tokenem semantycznym, który jest mapowany na kolor pasujący do interfejsu Narzędzi deweloperskich. Możliwe wartości to primary
, secondary
i tertiary,
z odpowiednimi wariantami -dark
i -light
, a także kolor error
.
Utwory
W momencie pisania tego artykułu wszystkie dane środowiska wykonawczego Angulara są dodawane do tego samego śladu (oznaczonego „🅰️ Angular”). Możesz jednak dodać do śladu wiele ścieżek, a nawet je pogrupować. Na przykład w przypadku tych wywołań interfejsu API console.timeStamp
:
console.timeStamp("Component 1", componentStart1, componentEnd1, "Components", "Client", "primary");
console.timeStamp("Component 2", componentStart2, componentEnd2, "Components", "Client", "primary");
console.timeStamp("Hook 1", hookStart, hookEnd, "Hooks", "Client", "primary");
console.timeStamp("Fetch data base", fetchStart, fetchEnd, "Server", "primary");
Dane byłyby uporządkowane w ścieżkach w ten sposób:

Korzystanie z osobnych ścieżek może być przydatne np. w przypadku aktywności asynchronicznej, wielu zadań wykonywanych równolegle lub grup aktywności na tyle odrębnych, że warto je rozdzielić w różnych obszarach interfejsu.
Dlaczego jest to ważne dla deweloperów Angulara
Celem tej bezpośredniej integracji jest zapewnienie bardziej intuicyjnej i wszechstronnej analizy wyników. Wyświetlając wewnętrzne dane o skuteczności Angulara bezpośrednio w panelu **Skuteczność**, deweloperzy uzyskają:
- Zwiększona widoczność: udostępnianie w szerszej osi czasu przeglądarki zdarzeń związanych z wydajnością Angulara, takich jak renderowanie komponentów czy cykle wykrywania zmian.
- Lepsze zrozumienie: dzięki bogatym w kontekst informacjom o wewnętrznych procesach Angulara możesz skuteczniej wskazywać wąskie gardła wydajności.
Włączanie integracji
Korzystanie z interfejsu Extensibility API jest oficjalnie dostępne w kompilacjach deweloperskich od wersji 20 Angulara. Aby go włączyć, musisz uruchomić globalne narzędzie `ng.enableProfiling()` w aplikacji lub w konsoli Narzędzi deweloperskich. Więcej informacji o integracji znajdziesz w [dokumentacji Angulara](https://angular.dev/best-practices/profiling-with-chrome-devtools).
Inne kwestie
Warto wziąć pod uwagę kilka ważnych kwestii.
Mapy źródeł i zminifikowany kod:
Mapy źródeł to powszechnie stosowane narzędzie, które ma na celu wypełnienie luki między spakowanym lub zminifikowanym kodem a jego odpowiednikiem napisanym przez autora.
Czy mapy źródeł nie powinny rozwiązywać problemu z zminifikowanym kodem w aplikacjach w pakietach?
Mapy źródłowe są przydatne, ale nie eliminują całkowicie problemów podczas profilowania złożonych, zminimalizowanych aplikacji internetowych. Mapy źródeł umożliwiają Narzędziom deweloperskim mapowanie zminifikowanego kodu z powrotem na oryginalny kod źródłowy, co ułatwia debugowanie. Jednak poleganie wyłącznie na mapach źródłowych w analizie skuteczności może mieć pewne ograniczenia. Na przykład samo użycie map źródeł nie wystarczy, aby wybrać sposób wizualnego oddzielenia wewnętrznych elementów frameworka od kodu napisanego przez autora. Interfejs API rozszerzalności zapewnia natomiast elastyczność w zakresie rozróżniania tych przypadków i prezentowania ich w sposób, który deweloper uzna za najwygodniejszy.
Rozszerzenia do Narzędzi deweloperskich w Chrome:
Rozszerzenia do Chrome korzystające z interfejsu DevTools API to powszechnie używane narzędzie do rozszerzania narzędzi deweloperskich.
Czy dedykowane profilerki (np. rozszerzenia Narzędzi Chrome dla programistów) są teraz niepotrzebne lub odradzane, skoro ten interfejs API jest dostępny?
Nie, ten interfejs API nie ma na celu zastąpienia ani zniechęcenia do tworzenia dedykowanych profilerów, takich jak rozszerzenia Narzędzi deweloperskich w Chrome. Mogą one nadal oferować specjalistyczne funkcje, wizualizacje i procesy dostosowane do konkretnych potrzeb. Interfejs API rozszerzalności panelu Wydajność ma na celu bezproblemową integrację danych niestandardowych z wizualizacjami przeglądarki w panelu Wydajność.
Dalsze działania
Perspektywy interfejsu Extensibility API.
Praca z większą liczbą platform i abstrakcji
Cieszymy się, że inne platformy i abstrakcje wdrażają ten interfejs API, aby ułatwić deweloperom profilowanie. Na przykład w React wprowadzono eksperymentalne wdrożenie interfejsu API w ramach tego frameworka. To narzędzie udostępnia informacje o renderowaniu komponentów po stronie klienta i serwera oraz dane interfejsów React Scheduling API. Więcej informacji o tym, jak włączyć tę funkcję, znajdziesz na stronie React.
Kompilacje produkcyjne
Jednym z celów tego interfejsu API jest współpraca z platformami i dostawcami abstrakcji w celu wdrożenia i włączenia instrumentacji w kompilacjach produkcyjnych. Może to mieć duży wpływ na wydajność aplikacji opracowanych przy użyciu tych abstrakcji, ponieważ deweloperzy będą mogli profilować aplikację tak, jak widzą ją użytkownicy. Uważamy, że interfejs console.timeStamp
API umożliwia to dzięki swojej szybkości i niskim kosztom. Obecnie jednak platformy nadal eksperymentują z interfejsem API i sprawdzają, które rodzaje instrumentacji są bardziej skalowalne i przydatne dla deweloperów.