コード判定 1:
<div id="div"> click me </div> <script> var div=document.getElementById("div"); div.addEventListener('click',function(){ alert('You have clicked me!'); }); for(var i =0; i<999999999;i++){ console.log(i); } </script>
実行すると、他に何も起こらなければすべてのブラウザがフリーズします。これは、JavaScript がシングルスレッドであるという事実に基づいて、上記の for ループが多すぎるため、大量の CPU リソースが消費され、ブラウザの UI レンダリングが一時停止されます。アニメーションが一時停止します。
さて、上記のコードを実装したいのですが、どうすればよいでしょうか?
Concurrent.Thread.js
このクラス ライブラリは基本的に setTimeout を使用して「偽のマルチスレッド」を実装します。 HTML5 WebWorker が登場する前は良い選択でした。たとえば、上記の「コード スニペット 1」を実装したい場合は、次のように記述できます (クラス ライブラリをダウンロードするには、[私] をクリックしてください):
コードスニペット 2:
<div id="div"> click me </div> <script src="Concurrent.Thread.js"></script> <script> Concurrent.Thread.create(function(){ var div=document.getElementById("div"); div.addEventListener('click',function(){ alert('You have clicked me!'); }); for(var i =0; i<9999999;i++){ console.log(i); } }); </script>
「新しいスレッド」は、このクラス ライブラリが提供する create メソッドを通じて作成できます。さらに、script タグの type 属性を text/x-script.multithreaded-js に設定することでも、同じ効果を達成できます:
コードフラグメント 3:
<div id="div"> click me </div> <script src="Concurrent.Thread.js"></script> <script type="text/x-script.multithreaded-js"> var div=document.getElementById("div"); div.addEventListener('click',function(){ alert('You have clicked me!'); }); for(var i =0; i<9999999;i++){ console.log(i); } </script>
ウェブワーカー
HTML5 は、上記のブラウザがスタックするというユーザー エクスペリエンスの悪さから目をそむけることができるでしょうか?
次に、古典的なフィボナッチ数列を使用してテストします。
コードフラグメント 4:
メインページ:
<div id="div"></div> <script> window.onload=function(){ var div=document.getElementById("div"); if(typeof(Worker)!=="undefined"){//在创建WebWorker之前,先判断浏览器是否支持 console.log("Start calculating...."); var time1= new Date()*1;//获得当前时间戳 var worker=new Worker("fibonacci.js");//创建WebWorker对象,并传递在新线程中将要执行的脚本的路径 worker.onmessage=function(e){ //监听从新线程发送过来的数据 div.innerHTML=e.data; var time2=new Date()*1; console.log("time spend:"+(time2-time1)+"ms"); } worker.postMessage(36);//向新线程发送数据 }else{ alert("Your browser do not support WebWoker"); } } </script> fibonacci.js: var fibonacci=function (n){ return n<3?n:(arguments.callee(n-1)+arguments.callee(n-2)); } onmessage=function(e){ var num=parseInt(e.data,10); postMessage(fibonacci(num));//向主页面发送数据 }
基本的な使用法はコード内にコメントされています。コンソールを見ると、すぐに実行時間が出力されることがわかります。そのため、フロントエンドで複雑かつ大規模な計算を実行するには WebWorker が適しているという結論に達しました。 WebWorker はクロスドメインをサポートしていないことに注意してください。ローカル テストでは引き続き http プロトコルを使用する必要があります。それ以外の場合は、Worker オブジェクトを作成できず、スクリプト エラーが報告されます。
複数の postMessage 操作を連続して実行する必要がある場合は、次のように work.postMessage を常に書かないことをお勧めします。
worker.postMessage(36); worker.postMessage(36); worker.postMessage(36);
現時点では WebWorker インスタンスが 1 つしかないため、postMessage は非同期ではなく順次実行されるため、そのパフォーマンスを最大限に活用できません。 WebWorkerインスタンスを複数作成することでデータを送信できます。
注意すべき点がいくつかあります:
1. WebWorker が URL を受け入れることによってワーカーを作成することを確認しました。jsonp の実装原理は、スクリプト タグを動的に挿入することによってデータをロードすることです。同じことを実現するために WebWorker を使用してみるとよいのではないでしょうか。 ? WebWorker はマルチスレッドであり、ブロッキングがないので、美しいと思いませんか?しかし実際には、実験の結果、WebWorker のパフォーマンスが満足のいくものではないことがわかりました。したがって、これはこのウイルスの得意分野ではないため、それに引き継がれるべきではありません。
2. WebWorker が他のソースから情報を受け取ると、実際にはサイトのセキュリティに隠れた危険がもたらされ、未知のソースからスクリプト情報を受け取ると、XSS インジェクション攻撃につながる可能性があります。したがって、上記の例で innerHTML を使用するのは安全ではありません。代わりに、最新のブラウザーが提供する innerText または textContent を使用して HTML タグを除外することができます。
今日はとても疲れたので寝たいので、とりあえずこれくらい書きます。