Omówienie procesów roboczych

Duża część treści tego kursu koncentrowała się na takich zagadnieniach jak ogólne kwestie związane z wydajnością kodu HTML, wskazówki dotyczące zasobów, optymalizacja różnych typów zasobów w celu przyspieszenia początkowego wczytywania strony i responsywność w odniesieniu do danych wejściowych użytkownika, a także leniwe ładowanie konkretnych zasobów.

Jest jednak jeden aspekt wydajności kodu JavaScript, który nie został jeszcze omówiony na tym kursie, a rola pracowników internetowych w zwiększaniu czasu reagowania na dane wejściowe, co omówimy w tym i następnym module.

JavaScript jest często opisany jako język jednowątkowy. W praktyce odnosi się to do wątku głównego, czyli pojedynczego wątku, w którym przeglądarka wykonuje większość działań widocznych w przeglądarce. Te zadania to m.in. tworzenie skryptów, niektóre rodzaje renderowania, analizowanie HTML i CSS oraz inne działania z perspektywy użytkownika, które zwiększają wygodę użytkowników. W rzeczywistości przeglądarki używają innych wątków, aby wykonywać zadania, do których Ty, deweloper, zazwyczaj nie masz bezpośredniego dostępu, na przykład wątki procesora graficznego.

Jeśli chodzi o JavaScript, ograniczasz się zwykle do wykonywania pracy w wątku głównym, ale tylko domyślnie. Istnieje możliwość zarejestrowania i używania dodatkowych wątków w języku JavaScript. Funkcja, która umożliwia wielowątkowość w języku JavaScript, nosi nazwę interfejsu Web Workers API.

Roboty internetowe są przydatne, jeśli musisz wykonać kosztowne obliczenia, których po prostu nie można uruchomić w wątku głównym bez wywoływania długich zadań, które sprawiają, że strona nie odpowiada. Takie zadania z pewnością mogą wpływać na interakcje z kolejnym wyrenderowaniem (INP) w witrynie, dlatego warto wiedzieć, kiedy masz jakąś pracę, którą można całkowicie zrezygnować z wątku głównego. Zwiększa to ilość miejsca na inne zadania w wątku głównym, co przyspiesza interakcje użytkowników.

Ten moduł i kolejna prezentacja przedstawiające konkretny przypadek użycia dotyczą pracowników sieciowych. Sama prezentacja pokazuje, jak za pomocą narzędzia internetowego odczytać metadane obrazu z pliku JPEG z głównego wątku oraz jak przywrócić metadane z powrotem do wątku głównego, aby użytkownik mógł je zobaczyć.

Jak uruchamiany jest skrypt internetowy

Skrypt internetowy jest rejestrowany przez utworzenie wystąpienia klasy Worker. Gdy to zrobisz, określisz, gdzie znajduje się kod instancji roboczej, która zostanie wczytana przez przeglądarkę, a następnie utworzy nowy wątek. Powstały wątek jest często nazywany wątkiem roboczym.

const myWebWorker = new Worker('/js/my-web-worker.js');

W pliku JavaScript instancji roboczej – w tym przypadku my-web-worker.js – możesz napisać kod, który będzie uruchamiany w osobnym wątku tej instancji.

Ograniczenia instancji roboczych

W przeciwieństwie do kodu JavaScript, który jest uruchamiany w wątku głównym, roboty internetowe nie mają bezpośredniego dostępu do kontekstu window i mają ograniczony dostęp do zapewnianych przez nie interfejsów API. Instancje robocze podlegają tym ograniczeniom:

  • Instancje robocze nie mają bezpośredniego dostępu do DOM.
  • Roboty internetowe mogą komunikować się z kontekstem window za pomocą potoku komunikacji, co oznacza, że mogą pośrednio uzyskać dostęp do DOM.
  • Zakres skryptu internetowego to self, a nie window.
  • Zakres instancji roboczej ma dostęp do podstawowych i konstrukcji JavaScriptu, a także do interfejsów API takich jak fetch i dosyć dużej liczby innych interfejsów API.

Jak pracownicy internetowi rozmawiają z window

Pracownik internetowy może komunikować się z kontekstem window wątku głównego za pomocą potoku komunikacji. Potok ten umożliwia przesyłanie danych do i z wątku głównego i instancji roboczej. Aby wysyłać dane z instancji roboczej do głównego wątku, musisz skonfigurować zdarzenie message w kontekście tej instancji (self)

// my-web-worker.js
self.addEventListener("message", () => {
  // Sends a message of "Hellow, window!" from the web worker:
  self.postMessage("Hello, window!");
});

Następnie w skrypcie w kontekście window w wątku głównym możesz otrzymać wiadomość z wątku instancji roboczej za pomocą kolejnego zdarzenia message:

// scripts.js

// Creates the web worker:
const myWebWorker = new Worker('/js/my-web-worker.js');

// Adds an event listener on the web worker instance that listens for messages:
myWebWorker.addEventListener("message", ({ data }) => {
  // Echoes "Hello, window!" to the console from the worker.
  console.log(data);
});

Potok komunikacji tej instancji roboczej to swego rodzaju wyjście z kontekstu tej instancji. Korzystając z niego, możesz wysyłać z instancji roboczej do window dane, których można użyć do aktualizacji DOM, lub wykonywać inne czynności, które trzeba wykonać w wątku głównym.

Sprawdź swoją wiedzę

W jakim wątku uruchamiana jest instancja robocza?

Wątek główny.
Spróbuj ponownie.
własny wątek (nazywany też wątkiem web worker).
Dobrze!
Wątek GPU.
Spróbuj ponownie.

Do czego ma dostęp robot internetowy?

Podstawowe elementy JavaScript, takie jak tablice i obiekty.
Dobrze!
Rygorystyczny podzbiór interfejsów API dostępnych w kontekście window, w tym fetch.
Dobrze!
Kontekst window, ale tylko pośrednio.
Dobrze!

Jak robot internetowy może uzyskać dostęp do kontekstu „window”?

Bezpośrednio przez odwoływanie się do członków obiektu window.
Spróbuj ponownie.
Robot internetowy nie może w żaden sposób uzyskać dostępu do elementu window.
Spróbuj ponownie.
Przez potok przesyłania wiadomości obsługiwany przez metodę postMessage w kontekście instancji roboczych (self).
Dobrze!

Następny krok: konkretny przypadek użycia komponentu internetowego

W następnym module szczegółowo opisujemy i opisujemy konkretny przypadek użycia. Ten moduł służy do pobierania pliku JPEG z podanego adresu URL i odczytywania jego metadanych Exif w tym pliku. Dane te są następnie wysyłane z powrotem do wątku głównego, aby mogły zostać wyświetlone użytkownikowi.