Articles

JavaScript Web Workers: początkujący's Guide

w 2019 roku ekosystem internetowy ewoluował do tego stopnia, że przeglądarka jest środowiskiem wykonawczym dla aplikacji zbudowanych w oparciu o JavaScript. Znajduje to odzwierciedlenie w szybkości, z jaką branża opracowuje nowe ramy, paradygmaty, Moduły ładujące i pakiety, Menedżery zależności, narzędzia do budowania i Menedżery pakietów rok po roku.

Kiedy JavaScript powstawał w początkach Internetu, kierunek rozwoju Internetu nie był jasny. Ze względu na ciągłe, szybkie zmiany w branży i ekosystemie, potrzebę wstecznej kompatybilności przeglądarek i standardów internetowych, ewolucja JavaScript stała się stałym strumieniem łatek, hacków i przemyśleń.

JavaScript Web workers load

dzisiejsze urządzenia mobilne zwykle mają 8+ Rdzeni PROCESORA lub 12+ rdzeni GPU. Procesory pulpitu i serwera mają do 16 rdzeni, 32 wątki lub więcej.

w tym środowisku dominujące środowisko programistyczne lub Skryptowe, które jest jednowątkowe, jest wąskim gardłem.

JavaScript jest jednowątkowy

oznacza to, że z założenia silniki JavaScript-pierwotnie przeglądarki — mają jeden główny wątek wykonania, a mówiąc prościej, proces lub funkcja B nie mogą być wykonane, dopóki proces lub funkcja a nie zostaną zakończone. Interfejs strony internetowej nie reaguje na żadne inne przetwarzanie JavaScript podczas wykonywania czegoś-jest to znane jako blokowanie DOM.

jest to strasznie nieefektywne, szczególnie w porównaniu z innymi językami.

jeśli przejdziemy do js Bin i uruchomimy ten kod w konsoli JavaScript przeglądarki:

//noprotecti = 0;while (i < 60000) { console.log("The number is " + i); i++;}

… cały jsbin.com witryna przestanie odpowiadać, dopóki przeglądarka nie zliczy i nie zaloguje się do 60 000.

nie będziemy mogli wchodzić w interakcje z niczym na stronie, ponieważ przeglądarka jest zajęta.

jest to stosunkowo mało wymagający proces obliczeniowy, a dzisiejsze aplikacje internetowe często wymagają znacznie bardziej wymagających zadań.

musimy być w stanie obliczyć rzeczy w tle, podczas gdy użytkownik bezproblemowo wchodzi w interakcję ze stroną.

Web Workers

W3C opublikowało pierwszy projekt standardu web workers w 2009 roku. Pełną specyfikację można znaleźć na stronie web Hypertext Application Technology Working Group – lub WHATWG-web standards body alternatywą dla W3C.

Web workers to Asynchroniczny system lub protokół dla stron internetowych do wykonywania zadań w tle, niezależnie od głównego wątku i interfejsu strony internetowej. Jest to izolowane środowisko, które jest izolowane od obiektuwindow, obiektudocument, bezpośredniego dostępu do Internetu i najlepiej nadaje się do długotrwałych lub wymagających zadań obliczeniowych.

oprócz Web workerów — systemu dedykowanego do wielowątkowości — istnieją inne sposoby osiągnięcia asnychronous przetwarzania w JavaScript, takie jak asynchroniczne wywołania Ajax i pętla zdarzeń.

aby to zademonstrować, wrócimy do js Bin i spróbujemy tego fragmentu:

console.log("A");setTimeout(function(){console.log("B");},2000);console.log("C");setTimeout(function(){console.log("D");},0);console.log("E");setTimeout(function(){console.log("F");},1000);

Kiedy to uruchomimy, nasza Sekwencja logów to A, C, E, D, F, B. Przeglądarka najpierw zaplanuje operacje bez limitu czasu, w miarę ich pojawiania się, a następnie wykona funkcje setTimeout() w kolejności ich odpowiednich określonych opóźnień. Jednak ta asynchroniczność nie powinna być automatycznie łączona z wielowątkowością. W zależności od komputera hosta, często może to być tylko jednowątkowy stos wywołań w kolejności, którą wyjaśniliśmy.

pracownicy sieci Web& wielowątkowość

jak wyjaśnia strona internetowa referencyjna JavaScript Mozilli, pracownicy sieci Web są „środkiem do uruchamiania skryptów w wątkach w tle.”

używamy ich w następujący sposób: sprawdzamy dostępność konstruktoraWorker() w przeglądarce, a jeśli jest dostępny, tworzymy instancję obiektu worker, z adresem URL skryptu jako argumentem. Skrypt ten zostanie wykonany w osobnym wątku.

skrypt musi być obsługiwany z tego samego hosta lub domeny ze względów bezpieczeństwa, i to jest również powód, dla którego pracownicy sieci nie będą działać, jeśli otworzymy plik lokalnie za pomocą schematufile://.

if (typeof(Worker) !== "undefined") { worker = new Worker("worker.js");} 

teraz definiujemy ten kod w pliku worker.js :

i = 0;while (i < 200000) { postMessage("Web Worker Counter: " + i); i++;}

Jeśli chcesz napisać wysokiej jakości pliki JavaScript web worker, sprawdź naszą książkę, JavaScript: Best Practice.

rozdzielenie wątków

ważną rzeczą do odnotowania jest rozdzielenie zakresuwindow Idocument w głównym wątku okna przeglądarki oraz zakresuworker.

aby skorzystać z wątkuworker, te dwa zakresy muszą być w stanie się komunikować. Aby to osiągnąć, używamy funkcji postMessage() w pliku worker.js — do wysyłania wiadomości do głównego wątku przeglądarki — i worker.onmessage słuchacza w głównym wątku do słuchania wiadomości worker.

możemy również wysyłać wiadomości z głównego wątku przeglądarki do worker wątku lub funkcji. Jedyną różnicą jest to, że odwracamy rzeczy i wywołujemy worker.postMessage() w wątku głównym i onmessage w wątku roboczym. Cytując referencje programistów Mozilli:

zauważ, żeonmessage IpostMessage() muszą być zawieszone naWorker Obiekt, gdy jest używany w głównym wątku skryptu, ale nie gdy jest używany w workerze. Dzieje się tak dlatego, że wewnątrz pracownika pracownik jest w rzeczywistości globalnym zakresem.

możemy użyć metodyterminate() w ten sam sposób, aby zakończyć wykonywanie naszego workera.

Mając to wszystko na uwadze, dochodzimy do tego przykładu:

index.html

<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>Web Workers Example</title> <style type="text/css"> body {padding-top:28px;} .output-cont {margin-left:12%; margin-top:28px;} .output-cont h3 {width:200px; height:100%;} .output-cont button {padding:4px 8px; font-size:1.1rem; font-family:sans-serif; } </style></head><body><div class="output-cont"><button onclick="testWorker()">start worker</button><h3></h3><button onclick="terminateWorker()">terminate worker</button></div><br/><div class="output-cont"><button onclick="testMainThread()">start blocking thread</button><h3></h3></div><br/><div class="output-cont"><button onclick="alert('browser responsive!')">test browser responsiveness</button></div> <script> var worker; function testWorker() { if (typeof(Worker) !== "undefined") { if (typeof(worker) == "undefined") { worker = new Worker("worker.js"); } worker.onmessage = function(event) { document.getElementById("workerOutput").innerHTML = event.data; }; } else { document.getElementById("workerOutput").innerHTML = "Web Workers are not supported in your browser"; } } function terminateWorker() { worker.terminate(); worker = undefined; } function testMainThread() { for (var i = 0; i < 200000; i++) { document.getElementById("mainThreadOutput").innerHTML = "Main Thread Counter: " + i; } } </script></body></html>

i worker.js:

i = 0;while (i < 200000) { postMessage("Web Worker Counter: " + i); i++;}

daje nam to możliwość przetestowania wpływu wykonania głównego wątku na zachowanie i wydajność strony w porównaniu z efektami Web workera.

w tym samouczku użyliśmy http-server do serwowania plików lokalnie.

JavaScript Web workers testowanie

teraz widzimy, że wątek roboczy nie blokuje interaktywności głównego procesu przeglądarki, a zapętlenie przez 200 000 liczb nie wpływa na główny wątek. Liczby w elemencie#workerOutput są aktualizowane przy każdej iteracji.

wątek blokujący, lub główny wątek, gdy jest zaangażowany w pętlę, blokuje całą interaktywność (ustawiliśmy tutaj liczbę iteracji na 200 000, ale będzie to jeszcze bardziej oczywiste, jeśli zwiększymy go do 2 000 000).

jeszcze jedną rzeczą, która wskazuje nam na zablokowany główny wątek jest to, że proces roboczy aktualizuje stronę przy każdej iteracji, a pętla w głównym wątku (ta zdefiniowana windex.html) aktualizuje tylko element#mainThreadOutput przy ostatniej iteracji.

dzieje się tak dlatego, że przeglądarka jest zbyt pochłonięta z liczeniem (for pętla), aby móc ponownie narysować DOM, więc robi to tylko wtedy, gdy jej działalność zfor pętla jest w pełni wykonana (na końcu pętli).

podsumowanie

w tym artykule przedstawiliśmy Web workers, technologię, która pomaga branży internetowej nadążyć za coraz bardziej wymagającymi aplikacjami internetowymi. Odbywa się to poprzez zapewnienie aplikacji internetowych sposobu na wykorzystanie wieloprocesorowych i wielowątkowych urządzeń poprzez nadanie kilku wielowątkowych supermocy JavaScript.

pracownicy sieci przekształcają środowiska przeglądarek mobilnych i desktopowych w platformy aplikacji, zapewniając im ścisłe środowisko wykonawcze. Ta ścisłość może zmusić nas do zapewnienia kopiowania obiektów między wieloma wątkami i planowania naszych aplikacji z uwzględnieniem tych ograniczeń.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *