Web Workers est une solution multithread javascript fournie par HTML5. Nous pouvons transmettre du code gourmand en calcul aux Web Workers pour qu'ils s'exécutent sans geler l'interface utilisateur.
1 : Comment utiliser Worker
Le principe de base de Web Worker est d'utiliser la classe Worker pour charger un fichier javascript dans le thread principal actuel de javascript afin d'ouvrir un nouveau thread, ce qui a pour effet d'exécution non bloquante et fournit des données entre le thread principal et le nouveau fil de discussion Interfaces échangées : postMessage, onmessage.
Alors comment l'utiliser, regardons un exemple :
Code JavaScriptCopier le contenu dans le presse-papiers
-
-
onmessage =fonction (evt){
-
var d = evt.data;
-
postMessage( d );
- }
Page HTML : test.html
Code XML/HTMLCopier le contenu dans le presse-papiers
- >
-
<html>
-
<<span style="largeur : auto; hauteur : auto; float : aucun;" id="20_nwp"><a style="texte- décoration : aucun;" mpid="20" cible ="_blank" href="http://cpro.baidu.com/ cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=head&k0=head&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs =1&seller_id=1&sid=45fdcf1cab219561&ssp2= 1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="20_nwl"><span style="couleur:#0000ff;font-size:14px;largeur:auto;hauteur:auto;float:aucun;">tête span>a>< /span>>
-
<méta http-equiv=" Content-Type" content="text/html; charset=utf-8"/>
-
<script type="text/ <span style="largeur : auto ; hauteur : auto ; float : aucun;" id="21_nwp">< a style="text-decoration : aucun;" mpid="21" cible="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di= 128&fv=0&is_app=0&jk=619521ab1ccffd45&k=javascript&k0=javascript&kdi0=0&luki=9&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0 &t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/ 1183.html&urlid=0" id="21_nwl">< ;span style="couleur:#0000ff;font-size:14px;largeur:auto; height:auto;float:none;">javascriptspan>a>span>">
- //WEB页主线程
-
var worker =nouveau Worker("worker.js"); //创建一个Worker对象并向它传递将在新线程中执行的脚本的URL
- worker.postMessage("hello world"); //向worker发送数据
-
worker.onmessage =function(evt){ //接收worker传过来的数据 <span style="largeur : auto; hauteur : auto; float : aucun ;" id="22_nwp">< a style="texte-décoration : aucun;" mpid="22" cible="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch =0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=����&k0=����&kdi0=0&luki=2&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid =0&t=tpclicked3_hc&tu=u1922429&u=http ://www.admin10000.com/document/1183.html&urlid=0" id="22_nwl"><span style="couleur :#0000ff ;font-size:14px;width:auto;height:auto;float:none;">函数 span>a>span>
-
console.log(evt.<span style= "largeur : auto; hauteur : auto; float : aucun;" id="23_nwp"><a style="texte-décoration : aucun;" mpid="23" cible="_blank" href="http://cpro.baidu.com/cpro/ ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=data&k0=data&kdi0=0&luki=4&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1& vendeur_id=1&sid=45fdcf1cab219561&ssp2=1&stid= 0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id= "23_nwl"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">data< /span>a>span>); //输出worker发送来的数据
- }
-
script>
-
tête>
-
<corps>corps>
-
html>
Après avoir ouvert test.html avec le navigateur Chrome, la console affiche "hello world", indiquant que l'exécution du programme a réussi.
À travers cet exemple, nous pouvons voir que l'utilisation des web Workers est principalement divisée en les parties suivantes
Fil principal WEB :
1. Chargez un fichier JS via worker = new Worker( url ) pour créer un travailleur et renvoyer une instance de travailleur.
2. Envoyez des données au travailleur via la méthode worker.postMessage(data).
3. Liez la méthode worker.onmessage pour recevoir les données envoyées par le travailleur.
4. Vous pouvez utiliser worker.terminate() pour terminer l'exécution d'un travailleur.
Nouveau fil de discussion pour les travailleurs :
1. Envoyez les données au thread principal via la méthode postMessage(data).
2. Liez la méthode onmessage pour recevoir les données envoyées par le thread principal.
2 : Que peut faire le travailleur
Maintenant que nous savons utiliser le web worker, à quoi sert-il et quels problèmes peut-il nous aider à résoudre. Regardons un exemple de la séquence de Fibonacci.
Tout le monde sait qu'en mathématiques, la suite de Fibonacci est définie de manière récursive : F0=0, F1=1, Fn=F(n-1) F(n-2) (n>=2, n∈N* ), et l'implémentation courante de javascript est :
Code JavaScriptCopier le contenu dans le presse-papiers
-
-
var fibonacci =fonction(n) {
-
return n <2? n : arguments.callee(n -1) arguments.callee(n -2);
}; -
- //fibonacci(36)
L'utilisation de cette méthode dans Chrome pour exécuter la séquence de Fibonacci de 39 prend 19 097 millisecondes, mais lorsqu'il s'agit de calculer 40, le navigateur indique directement que le script est occupé.
Étant donné que JavaScript est exécuté dans un seul thread, le navigateur ne peut pas exécuter d'autres scripts JavaScript pendant le processus de calcul de la séquence, et le thread de rendu de l'interface utilisateur sera également suspendu, provoquant l'entrée du navigateur dans un état zombie. Utiliser un web worker pour placer le processus de calcul de la séquence dans un nouveau thread évitera cette situation. Voir l'exemple spécifiquement :
Code JavaScript
Copier le contenu dans le presse-papiers
HTML Ouvrir:fibonacci.html
Code XML/HTMLConfiguration du code international
- >
-
<html>
-
<<span style="largeur : auto; hauteur : auto; float : aucun;" id="11_nwp"><a style="texte- décoration : aucun;" mpid="11" cible ="_blank" href="http://cpro.baidu.com/ cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=head&k0=head&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs =1&seller_id=1&sid=45fdcf1cab219561&ssp2= 1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="11_nwl"><span style="couleur:#0000ff;font-size:14px;largeur:auto;hauteur:auto;float:aucun;">tête span>a>< /span>>
-
<méta http-equiv=" Content-Type" content="text/html; charset=utf-8"/>
-
<titre>web worker fibonacci titre>
-
<script type="text/ <span style="largeur : auto ; hauteur : auto ; float : aucun;" id="12_nwp">< a style="text-decoration : aucun;" mpid="12" cible="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di= 128&fv=0&is_app=0&jk=619521ab1ccffd45&k=javascript&k0=javascript&kdi0=0&luki=9&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0 &t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/ 1183.html&urlid=0" id="12_nwl">< ;span style="couleur:#0000ff;font-size:14px;largeur:auto; height:auto;float:none;">javascriptspan>a>span>">
-
onload =fonction(){
-
var worker =nouveau Worker('fibonacci.js');
- worker.addEventListener('message', function(event) {
-
var timer2 = (new Date()).valueOf();
-
console.log( '结果:' event.<span style ="largeur : auto; hauteur : auto; float : aucun;" id="13_nwp" ><un style=" text-decoration : aucun;" mpid="13" cible="_blank" href="http://cpro.baidu. com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=data&k0=data&kdi0=0&luki=4&n=10&p=baidu&q=06011078_cpr&rb=0 &rs=1&seller_id=1&sid= 45fdcf1cab219561&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="13_nwl"><span style= "couleur:#0000ff;font-size:14px;largeur:auto;hauteur:auto;float:aucun;">donnéesspan>a> span>, '时间:' timer2, '用时:' ( timer2 - timer ) );
- }, FAUX);
-
var minuterie = (new Date()).valueOf();
- console.log('开始计算:40','时间:' timer );
- setTimeout(function(){
-
console.log('定时器<span style="largeur : auto; hauteur : auto; float : aucun;" id="14_nwp" ><a style="texte-décoration : aucun;" mpid="14" cible="_blank" href="http://cpro.baidu.com/cpro /ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=����&k0=����&kdi0=0&luki=2&n=10&p=baidu&q=06011078_cpr&rb=0&rs =1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="14_nwl"><span style="couleur:#0000ff;font-size:14px;largeur:auto;hauteur:auto;float:aucun;">函数span>a>span>在计算数列时执行了', '时间:' (new Date()).valueOf( ) );
- },1000 );
- worker.postMessage(40);
- console.log('我在计算数列的时候执行了', '时间:' (new Date()).valueOf() );
- }
-
script>
-
<span style= "largeur : auto; hauteur : auto; float : aucun;" id="15_nwp"><a style="texte -décoration : aucun;" mpid="15" cible="_blank" href="http://cpro.baidu.com /cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=head&k0=head&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb= 0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2 =1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id= "15_nwl"><span style="couleur:#0000ff;font-size:14px;largeur:auto;hauteur:auto;float:aucun;">têtespan>a>< ;/span>>
-
<corps>
-
corps>
-
html>
在Chrome中打开fibonacci.html,控制台得到如下输出:
开始计算:40 时间:1316508212705
我在计算数列的时候执行了 时间:1316508212734
定时器
Code XML/HTML复制内容到剪贴板
- <span style="largeur : auto ; hauteur : auto; float : aucun;" id="9_nwp"><a style="texte-décoration : aucun ;" mpid="9" cible=" _blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id =0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=����&k0=����&kdi0=0&luki=2&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf 1cab219561&ssp2=1&stid=0&t =tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id=" 9_nwl"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">函数 span>a>durée>
在计算数列时执行了 时间:1316508213735
结果:102334155 时间:1316508262820 用时:50115
这个例子说明在worker中执行的fibonacci数列的计算并不会影响到主线程的代码执行,完全在自己独立的线程中计算,只是在计算完成之后将结果发回主线程。
利用Web Worker我们可以在前端执行一些复杂的大量运算而不会影响页面的展示,并且不会弹出恶心的脚本正忙提示。
下面这个例子使用了Web Worker来计算场景中的像素,一个worker只计算一块像素值。
http://nerget.com/rayjs-mt/rayjs.html
三:Travailleur的其他尝试
JSONP的请求呢,大家知道jsonp是通过插入script标签来加载json数据的,而script元素在加载和执行过程中都是阻塞式的,如果能利用web worker实现异步加载将会非常不错。
下面这个例子将通过 web worker、jsonp、ajax三种不同的方式来加载一个169.42KB大小的JSON数据
Code JavaScript
复制内容到剪贴板
-
-
fonction $E(id) {
-
return document.getElementById(id);
- }
-
onload =fonction() {
-
-
$E('workerLoad').onclick =fonction() {
-
var url ='http://js.wcdn.cn/aj/mblog/face2' ;
-
var d = (nouveau Date()).valueOf();
-
var worker =nouveau Worker(url);
-
worker.onmessage =fonction(obj) {
-
console.log('web worker : ' ((new Date()).valueOf() - d));
- } ;
- } ;
-
-
$E('jsonpLoad').onclick =fonction() {
-
var url ='http://js.wcdn.cn/aj/mblog/face1' ;
-
var d = (nouveau Date()).valueOf();
- STK.core.io.scriptLoader({
-
méthode :'post',
- url : url,
-
onComplete : fonction() {
-
console.log('jsonp: ' ((new Date()).valueOf() - d));
- }
- });
- };
-
-
$E('ajaxLoad').onclick =fonction() {
-
var url ='http://js.wcdn.cn/aj/mblog/face' ;
-
var d = (nouveau Date()).valueOf();
- STK.core.io.ajax({
- url : url,
-
onComplete : fonction(json) {
-
console.log('ajax: ' ((nouveau Date()).valueOf() - d));
- }
- });
- } ;
- } ;
HTML页面:/aj/webWorker/worker.html
Code XML/HTML复制内容到剪贴板
- >
-
<html>
-
<<span style="largeur : auto; hauteur : auto; float : aucun;" id="4_nwp"><a style="texte- décoration : aucun;" mpid="4" cible ="_blank" href="http://cpro.baidu.com/ cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk=619521ab1ccffd45&k=head&k0=head&kdi0=0&luki=6&n=10&p=baidu&q=06011078_cpr&rb=0&rs =1&seller_id=1&sid=45fdcf1cab219561&ssp2= 1&stid=0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/1183.html&urlid=0" id="4_nwl"><span style="couleur:#0000ff;font-size:14px;largeur:auto;hauteur:auto;float:aucun;">tête span>a>< /span>>
-
<méta http-equiv=" Content-Type" content="text/html; charset=utf-8"/>
-
<titre>Exemple de travail : charger < span style="largeur : auto; hauteur : auto; float : aucun ;" id="5_nwp"><a style="text-decoration : aucun;" mpid= "5" cible="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di=128&fv=0&is_app=0&jk =619521ab1ccffd45&k=data&k0=data&kdi0=0&luki=4&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0&t=tpclicked3_hc&tu=u192242 9&u=http://www.admin10000.com/document/1183.html&urlid=0 " id="5_nwl"><span style="couleur:#0000ff;font-size:14px;largeur:auto;hauteur:auto;float :aucun;">donnéesspan>< ;/a>span> titre>
-
<script src="http : //js.t.sinajs.cn/STK/js/gaea.1.14.js" type="text/< ;span style="largeur : auto ; hauteur : auto ; float : aucun;" id="6_nwp">< a style="text-decoration : aucun;" mpid="6" cible="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di= 128&fv=0&is_app=0&jk=619521ab1ccffd45&k=javascript&k0=javascript&kdi0=0&luki=9&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid=0 &t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/ 1183.html&urlid=0" id="6_nwl">< ;span style="couleur:#0000ff;font-size:14px;largeur:auto; height:auto;float:none;">javascriptspan>a>span>">script>
-
<script type="texte/ javascript" src="http://js.wcdn.cn/aj/webWorker/core.js" >script>
-
tête>
-
<corps>
-
<entrée type="bouton" id="workerLoad" value="web worker加载">input>
-
<entrée type="bouton" id="jsonpLoad" valeur="jsonp加载">entrée>
-
<entrée type="bouton" id="<span style="largeur : auto ; hauteur : auto ; float : aucun;" id="7_nwp">< a style="text-decoration : aucun;" mpid="7" cible="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?adclass=0&app_id=0&c=news&cf=1001&ch=0&di= 128&fv=0&is_app=0&jk=619521ab1ccffd45&k=ajax&k0=ajax&kdi0=0&luki=8&n=10&p=baidu&q=06011078_cpr&rb=0&rs=1&seller_id=1&sid=45fdcf1cab219561&ssp2=1&stid= 0&t=tpclicked3_hc&tu=u1922429&u=http://www.admin10000.com/document/ 1183.html&urlid=0" id="7_nwl">< ;span style="couleur:#0000ff;font-size:14px;largeur:auto; height:auto;float:none;">ajaxspan>a>span>Charger" valeur="ajax加载">entrée>
-
corps>
-
html>
设置HOST
127.0.0.1 js .wcdn.cn
通过 http://js.wcdn.cn/aj/webWorker/worker.html 得到控制台输出:
web worker : 174
jsonp : 25
ajax : 38
何度か試した結果、jsonp と ajax を介してデータをロードする時間はそれほど変わらないことがわかりました。また、Web ワーカーのロード時間は常に高いレベルにあるため、Web ワーカーを使用してデータをロードするのはまだ比較的早いです。大量のデータがあっても遅いため、ワーカーが新しいスレッドを初期化するのに時間がかかる可能性があります。ロード中にブロックされないこと以外の利点はありません。
それでは、Web ワーカーはクロスドメインの JS 読み込みをサポートできますか? 今回は、http://127.0.0.1/aj/webWorker/worker.html を通じてページにアクセスします。「Web ワーカーの読み込み」読み込みボタンをクリックすると、Chrome はダウンロード FF6 では応答がなく、エラーが表示されます。このことから、Web ワーカーは JS のクロスドメイン読み込みをサポートしていないことがわかります。これは、静的ファイルを別の静的サーバーにデプロイする Web サイトにとっては悪いニュースです。
Web Worker は同じドメイン内の JSON データをロードするためにのみ使用できますが、Ajax はすでにこれを実行でき、より効率的で多用途です。ワーカーに得意なことをやらせましょう。
4: 概要
Web ワーカーは優しそうに見えますが、悪魔がいっぱいです。
私たちにできること:
1. JS をロードして、メインプロセスをハングさせることなく多数の複雑な計算を実行し、postMessage、onmessage を通じて通信できます
2. importScripts(url) を通じてワーカーに追加のスクリプト ファイルをロードできます
3. setTimeout()、clearTimeout()、setInterval()、clearInterval()を使用できます
4. XMLHttpRequest を使用してリクエストを送信できます
5. ナビゲーターの一部のプロパティにアクセスできます
制限事項:
1. ドメインを越えて JS をロードすることはできません
2.ワーカー内のコードはDOMにアクセスできません
3. さまざまなブラウザーでのワーカーの実装には一貫性がありません。たとえば、FF ではワーカーでの新しいワーカーの作成が許可されていますが、
では許可されていません。
4. すべてのブラウザがこの新機能をサポートしているわけではありません