Kod Penghakiman 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>
Apabila dilaksanakan, semua penyemak imbas akan membeku jika tiada apa-apa lagi yang berlaku, kerana terdapat terlalu banyak untuk gelung di atas, yang menggunakan banyak sumber CPU Berdasarkan fakta bahawa JavaScript adalah satu thread, pemaparan UI penyemak imbas digantung dan menyebabkan animasi digantung.
Kini persoalannya datang, saya hanya mahu melaksanakan kod di atas, apa yang perlu saya lakukan?
Concurrent.Thread.js
Pustaka kelas ini pada asasnya menggunakan setTimeout untuk melaksanakan "pelbagai benang palsu". Merupakan pilihan yang baik sebelum HTML5 WebWorker keluar. Sebagai contoh, jika kita ingin melaksanakan "coretan kod 1" di atas, kita boleh menulisnya seperti ini (klik saya untuk memuat turun perpustakaan kelas):
Coretan kod 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>
"Benang baharu" boleh dibuat melalui kaedah cipta yang disediakan oleh perpustakaan kelas ini. Selain itu, menetapkan atribut jenis teg skrip kepada text/x-script.multithreaded-js juga boleh mencapai kesan yang sama:
Kod pecahan tiga:
<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>
WebWorker
Bagaimanakah HTML5 boleh menutup mata terhadap pengalaman pengguna yang buruk bagi penyemak imbas di atas yang tersekat?
Seterusnya kami menggunakan jujukan Fibonacci klasik untuk menguji:
Kod serpihan empat:
Halaman utama:
<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));//向主页面发送数据 }
Penggunaan asas telah diulas dalam kod Melihat pada konsol, anda dapat melihat bahawa masa pelaksanaan akan dicetak tidak lama lagi. Jadi kami sampai pada kesimpulan bahawa WebWorker sesuai untuk melakukan pengiraan yang kompleks dan berskala besar pada bahagian hadapan. Perlu diingat bahawa WebWorker tidak menyokong ujian rentas domain masih harus menggunakan protokol http. Jika tidak, objek Worker tidak boleh dibuat dan ralat skrip akan dilaporkan.
Jika kita perlu melakukan beberapa operasi postMessage secara berterusan, sebaiknya jangan menulis work.postMessage sepanjang masa, seperti ini:
worker.postMessage(36); worker.postMessage(36); worker.postMessage(36);
Oleh kerana hanya terdapat satu tika WebWorker pada masa ini, postMessage akan dilaksanakan secara berurutan dan bukannya secara tak segerak, jadi prestasinya tidak dapat digunakan sepenuhnya. Data boleh dihantar dengan mencipta berbilang contoh WebWorker.
Beberapa perkara yang perlu diambil perhatian ialah:
1. Kami mendapati bahawa WebWorker mencipta pekerja dengan menerima url, dan prinsip pelaksanaan jsonp adalah untuk memuatkan data dengan memasukkan teg skrip secara dinamik, bukankah lebih baik jika kami cuba menggunakan WebWorker untuk mencapai perkara yang sama ? Kerana WebWorker berbilang benang dan tidak mempunyai sekatan, bukankah ia cantik? Tetapi sebenarnya, selepas eksperimen, kami mendapati bahawa prestasi WebWorker tidak memuaskan. Jadi ini bukan perkara yang bagus, kita tidak sepatutnya membiarkannya mengambil alih.
2. Apabila WebWorker menerima maklumat daripada sumber lain, ia sebenarnya membawa bahaya tersembunyi kepada keselamatan tapak Jika ia menerima maklumat skrip daripada sumber yang tidak diketahui, ia mungkin membawa kepada serangan suntikan XSS. Oleh itu, perkara ini perlu diwaspadai, sebenarnya, adalah tidak selamat untuk menggunakan innerHTML dalam contoh kami di atas. Anda boleh menggunakan innerText atau textContent yang disediakan oleh pelayar moden untuk menapis teg html.
Saya agak letih hari ini dan mahu tidur, jadi saya akan menulis sebanyak ini buat masa ini.