Articles

JavaScript Web Workers: a Beginners Guide

vuonna 2019 web-ekosysteemi on kehittynyt siihen pisteeseen, että selain on JavaScript-alustalle rakennettujen sovellusten suoritusympäristö. Tämä näkyy siinä, miten nopeasti teollisuus kehittää uusia kehyksiä, paradigmoja, moduulikuormaajia ja niputtajia, riippuvuushallintoja, rakentamistyökaluja ja pakettijohtajia vuodesta toiseen.

kun JavaScript sai alkunsa internetin alkuaikoina, Internetin kehityksen suunta ei ollut selvä. Koska jatkuva, nopea muutos teollisuuden ja ekosysteemin, tarve taaksepäin-yhteensopivuus selaimet ja web-standardit, evoluutio JavaScript tuli jatkuva virta laastaria, hakata ja afterthoughts.

JavaScript web workers load

nykypäivän mobiililaitteissa on yleensä 8+ CPU-ydintä eli 12+ GPU-ydintä. Työpöytä-ja palvelinsuorittimissa on jopa 16 ydintä, 32 säiettä tai enemmän.

tässä ympäristössä vallitseva ohjelmointi-tai skriptausympäristö, joka on yksikierteinen, on pullonkaula.

JavaScript on Yksikierteinen

tämä tarkoittaa, että suunnittelultaan JavaScript-moottoreissa — alun perin selaimissa — on yksi pääkierre suorittamisesta, eikä yksinkertaisesti sanottuna prosessia tai funktiota B voida suorittaa ennen kuin prosessi tai funktio A on valmis. Web-sivun käyttöliittymä ei reagoi mihinkään muuhun JavaScript-käsittelyyn, kun se on miehitetty suorittamalla jotain-tätä kutsutaan DOM-estoksi.

Tämä on hirveän tehotonta varsinkin muihin kieliin verrattuna.

jos menemme JS Bin: iin ja suoritamme tämän koodin selaimen JavaScript-konsolissa:

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

… koko jsbin.com verkkosivusto ei reagoi, kunnes selain laskee — ja lokit-60 000: een.

emme voi olla vuorovaikutuksessa minkään sivulla olevan kanssa, koska selain on varattu.

nyt tämä on suhteellisen vaatimaton laskentaprosessi, ja nykypäivän verkkosovelluksiin liittyy usein paljon vaativampia tehtäviä.

meidän täytyy pystyä laskemaan asioita taustalla samalla, kun käyttäjä on saumattomasti vuorovaikutuksessa sivun kanssa.

Web Workers

W3C julkaisi ensimmäisen luonnoksen web workers standardista vuonna 2009. Täydellinen erittely löytyy Web Hypertext Application Technology Working Groupin verkkosivuilta-tai WHATWG-web-standardointielimen vaihtoehto W3C: lle.

Web workers on asynkroninen järjestelmä tai protokolla, jolla verkkosivut voivat suorittaa tehtäviä taustalla, riippumatta pääkierteestä ja web-sivujen käyttöliittymästä. Se on eristetty ympäristö, joka on eristetty window objekti, document objekti, suora internet-yhteys ja soveltuu parhaiten pitkäkestoisiin tai vaativiin laskennallisiin tehtäviin.

lisäksi web workers — järjestelmä omistettu monilukuun — on olemassa muita tapoja saavuttaa Asnykroninen käsittely JavaScript, kuten asynkroninen Ajax puhelut, ja event loop.

tämän osoittamiseksi palaamme JS Biniin ja kokeilemme tätä pätkää:

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);

kun suoritamme tämän, lokijaksomme on A, C, E, D, F, B. Selain ajoittaa ensin toiminnot ilman aikakatkaisua, sitä mukaa kuin ne tulevat, ja suorittaa sitten setTimeout() toiminnot niiden määrittämien viiveiden mukaisessa järjestyksessä. Tätä asynkronisuutta ei kuitenkaan pitäisi automaattisesti yhdistää monilukuun. Riippuen isäntä kone, tämä voi usein olla vain yhden langan pino puhelut järjestyksessä selitimme.

Verkkotyöntekijät & Multitreading

kuten Mozillan JavaScript-viitesivusto kertoo, verkkotyöntekijät ovat ”keino verkkosisällön komentosarjojen suorittamiseen taustaketjuissa.”

käytämme niitä seuraavalla tavalla: tarkistamme Worker() constructorin saatavuuden selaimessa, ja jos se on saatavilla, instantioimme työobjektin, jonka argumenttina on skriptin URL. Tämä skripti suoritetaan erillisellä langalla.

skripti on tarjottava samalta palvelimelta tai verkkotunnukselta turvallisuussyistä, ja se on myös syy siihen, että verkkotyöntekijät eivät toimi, jos avaamme tiedoston paikallisesti file:// scheme.

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

nyt määrittelemme tämän koodin worker.js tiedostossa:

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

Jos haluat kirjoittaa laadukkaita JavaScript-verkkotyöntekijätiedostoja, tutustu kirjaamme JavaScript: Best Practice.

kierteiden erottaminen

tärkeää tässä on huomata window ja document toteutuksen laajuus varsinaisessa selainikkunan kierteessä ja worker laajuus.

voidakseen käyttää worker säiettä näiden kahden ulottuman on kyettävä kommunikoimaan. Tämän saavuttamiseksi käytämmepostMessage() funktiotaworker.js tiedostoa — lähettämään viestejä pääselaimen kierteelle — jaworker.onmessage kuuntelija pääkierteessä kuuntelemaanworker viestejä.

voimme lähettää viestejä myös pääselaimen kierteestä worker säiettä tai toimintoa. Ainoa ero on se, että käännämme asiat ja kutsumme worker.postMessage() pääkierteeseen ja onmessage työläiskierteeseen. Lainatakseni Mozillan kehittäjäviittausta:

huomaa, että onmessage ja postMessage() on ripustettava Worker objekti, kun sitä käytetään pääkirjoituskierteessä, mutta ei silloin, kun sitä käytetään työläisessä. Tämä johtuu siitä, että työntekijän sisällä työntekijä on käytännössä globaali ulottuvuus.

voimme käyttää terminate() menetelmää samalla tavalla, lopettaaksemme työläisemme suorittamisen.

kaikki tämä mielessä, päädymme tähän esimerkkiin:

indeksi.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>

ja työläinen.js:

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

Tämä antaa meille mahdollisuuden testata pääkierteen suorittamisen vaikutuksia sivun käyttäytymiseen ja suorituskykyyn verrattuna verkkotyöntekijän vaikutuksiin.

tässä opetusohjelmassa käytettiin http-server palvelemaan tiedostoja paikallisesti.

JavaScript Web-työntekijöiden testaus

nyt voimme nähdä, että työlanka ei estä pääselainprosessin vuorovaikutteisuutta, eikä 200 000 numeron läpi loopaaminen vaikuta pääkierteeseen. #workerOutput elementin numerot päivittyvät jokaisessa iteraatiossa.

estolanka eli pääkierre, kun se kytketään silmukkaan, estää kaiken interaktiivisuuden (olemme asettaneet iteraatioiden määrän tässä 200 000: een, mutta se on vielä selvempää, jos nostamme sen 2 000 000: een).

vielä yksi asia, joka osoittaa meidät tukkeutuneeseen pääkierteeseen, on se, että työprosessi päivittää sivun jokaisessa iteraatiossa, ja pääkierteen silmukka (se, joka on määritelty index.html) päivittää vain #mainThreadOutput elementin viimeisessä iteraatiossa.

Tämä johtuu siitä, että selain on liian kuluttunut laskemiseen (for loop) voidakseen piirtää DOM: n uudelleen, joten se tekee sen vasta, kun for loop on täysin valmis (silmukan lopussa).

johtopäätös

tässä artikkelissa esittelimme web workers-tekniikan, joka auttaa web-teollisuutta pysymään yhä vaativampien verkkosovellusten perässä. Tämä tapahtuu tarjoamalla tapa web apps hyödyntää multi-prosessori ja multi-kierteitetyt laitteet lahjoittamalla joitakin multi-kierteitetyt supervoimia JavaScript.

Verkkotyöntekijät muuttavat mobiili-ja työpöytäselainympäristöt sovellusalustoiksi tarjoten niille tiukan suoritusympäristön. Tämä tiukkuus voi pakottaa meidät järjestämään esineiden kopioinnin useiden säikeiden välillä ja suunnittelemaan sovelluksemme näitä rajoitteita silmällä pitäen.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *