JavaScript Web Workers:A Beginner ' S Guide
i 2019 har webøkosystemet utviklet seg til et punkt der nettleseren er et kjøringsmiljø for applikasjoner bygget På JavaScript. Dette gjenspeiles i hastigheten som bransjen kommer opp med nye rammer, paradigmer, modul lastere og bundlers, avhengighet ledere, bygge verktøy og pakke ledere år etter år.
Når JavaScript ble oppfattet i de tidlige dagene av internett, var retningen for internettutvikling ikke klar. På grunn av den konstante, raske endringen i industrien og økosystemet, behovet for bakoverkompatibilitet av nettlesere og webstandarder, ble Utviklingen Av JavaScript en konstant strøm av patcher, hack og ettertanke.
Dagens mobile enheter kommer normalt med 8 + CPU-kjerner, eller 12 + GPU-kjerner. Desktop Og server Cpuer har opptil 16 kjerner, 32 tråder eller mer.
i dette miljøet er det en flaskehals å ha et dominerende programmerings-eller skriptmiljø som er enkelttrådet.
JavaScript Er enkelttrådet
Dette betyr at JavaScript — motorer-opprinnelig nettlesere-har en hovedtråd for utførelse, og for å si det enkelt, kan prosess Eller funksjon B ikke utføres før prosess Eller funksjon A er ferdig. EN webside UI er ikke svarer til noen Annen JavaScript behandling mens det er opptatt med å utføre noe-dette er kjent SOM DOM blokkering.
dette er veldig ineffektivt, spesielt i forhold til andre språk.
hvis VI går TIL Js Bin og kjører denne koden i Nettleserens JavaScript-konsoll:
//noprotecti = 0;while (i < 60000) { console.log("The number is " + i); i++;}
… hele jsbin.com nettstedet vil ikke svare til nettleseren teller – og logger-til 60.000.
Vi vil ikke kunne samhandle med noe på siden, fordi nettleseren er opptatt.
Nå er dette en relativt lite krevende prosess, og dagens webapper involverer ofte mye mer krevende oppgaver.
Vi må kunne beregne ting i bakgrunnen mens brukeren sømløst samhandler med siden.
Web Workers
W3C publiserte et første utkast til web workers standard i 2009. Den fullstendige spesifikasjonen kan bli funnet På Web Hypertext Application Technology Working Group nettsted-ELLER WHATWG – en web standards body alternativ TIL W3C.
Web workers er et asynkront system, eller protokoll, for websider til å utføre oppgaver i bakgrunnen, uavhengig av hovedtråden OG nettstedet UI. Det er et isolert miljø som er isolert fra window
objekt,document
objekt, direkte internett-tilgang og er best egnet for langvarige eller krevende beregningsoppgaver.Bortsett fra webarbeidere-et system dedikert til multithreading-finnes det andre måter å oppnå asnychronous behandling I JavaScript, for eksempel Asynkrone Ajax-samtaler og event loop.
for å demonstrere dette, vil vi gå tilbake TIL Js Bin og prøve denne koden:
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);
når vi kjører dette, er loggsekvensen vårA, C, E, D, F, B
. Nettleseren først tidsplaner operasjoner uten timeout, som de kommer, og deretter utfører densetTimeout()
funksjoner i rekkefølgen av sine respektive angitte forsinkelser. Denne asynkronisiteten bør imidlertid ikke automatisk sammenflettes med multithreading. Avhengig av vertsmaskinen kan dette ofte bare være en enkelttrådsstabel av samtalene i den rekkefølgen vi forklarte.
Webarbeidere& Multithreading
som Mozillas JavaScript-referansenettsted forklarer, er webarbeidere et » middel for webinnhold for å kjøre skript i bakgrunnstråder.»
vi bruker dem på følgende måte: vi sjekker tilgjengeligheten avWorker()
konstruktøren i nettleseren, og hvis den er tilgjengelig, starter vi et arbeiderobjekt, MED skriptadressen SOM argument. Dette skriptet vil bli utført på en egen tråd.
skriptet må serveres fra samme vert eller domene av sikkerhetsgrunner, og det er også grunnen til at webarbeidere ikke vil fungere hvis vi åpner filen lokalt med en file://
– skjema.
if (typeof(Worker) !== "undefined") { worker = new Worker("worker.js");}
nå definerer vi denne koden iworker.js
fil:
i = 0;while (i < 200000) { postMessage("Web Worker Counter: " + i); i++;}
hvis du ønsker å skrive Høykvalitets JavaScript web worker filer, sjekk ut vår bok, JavaScript: Best Practice.
Separasjonen Av Tråder
en viktig ting å merke seg her er separasjonen av window
og document
omfanget av utførelse i hovedleservinduet tråd, og worker
omfang.
for å kunne bruke worker
tråden, må disse to områdene kunne kommunisere. For å oppnå dette bruker vi postMessage()
funksjonen i worker.js
filen-for å sende meldinger til hovedlesertråden – ogworker.onmessage
lytteren i hovedtråden for å lytte til worker
meldinger.
vi kan også sende meldinger fra hovedlesertråden til worker
tråd eller funksjon. Den eneste forskjellen er at vi reverserer ting, og kaller worker.postMessage()
på hovedtråden, og onmessage
på arbeidstråden. For å sitere Mozillas utviklerreferanse:
Legg Merke til at
onmessage
ogpostMessage()
må henges avWorker
– objektet når det brukes i hovedskripttråden, men ikke når det brukes i arbeideren. Dette er fordi, innenfor arbeideren, er arbeideren effektivt det globale omfanget.
Vi kan bruketerminate()
metoden på samme måte, for å avslutte vår arbeiders utførelse.
Med alt dette i tankene kommer vi til dette eksemplet:
indeks.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>
og arbeider.js:
i = 0;while (i < 200000) { postMessage("Web Worker Counter: " + i); i++;}
dette gir oss muligheten til å teste ut effektene av hovedtrådutførelse på sideatferd og ytelse i forhold til webarbeiderens effekter.
i denne opplæringen brukte vi http-server
for å betjene filene lokalt.
Nå kan Vi se at arbeidertråden ikke blokkerer interaktiviteten til hovedleserprosessen, og looping gjennom 200.000 tall påvirker ikke hovedtråden. Tallene i#workerOutput
– elementet oppdateres på hver iterasjon.
blokkeringstråden, eller hovedtråden, når den er engasjert i en løkke, blokkerer all interaktivitet (vi har satt antall iterasjoner til 200.000 her, men det vil bli enda tydeligere hvis vi øker den til 2.000.000).en ting som peker oss til en blokkert hovedtråd er at arbeidsprosessen oppdaterer siden på hver iterasjon, og sløyfen i hovedtråden (den som er definert i index.html
) oppdaterer bare #mainThreadOutput
– elementet på den siste iterasjonen.
dette skyldes at nettleseren er for opptatt av å telle (for
loop) for å kunne redraw DOM, så det gjør det bare når sin virksomhet med for
loop er fullt ferdig (på slutten av sløyfen).
Konklusjon
i denne artikkelen introduserte vi webarbeidere, en teknologi som hjelper nettbransjen med å holde tritt med stadig mer krevende webapper. Dette gjøres ved å gi en måte for web apps å utnytte multi-prosessor og multi-threaded enheter ved å skjenke noen multi-threaded superkrefter Til JavaScript.
Webarbeidere gjør mobile og stasjonære nettlesermiljøer til applikasjonsplattformer, og gir dem et strengt utførelsesmiljø. Denne strengheten kan tvinge oss til å sørge for kopiering av objekter mellom flere tråder, og å planlegge våre applikasjoner med disse begrensningene i tankene.