Web Worker線程處理
1 瀏覽器把所有事件都通過操作系統安排到事件隊列中(例如:你去一個·窗口買菜,需要排隊);瀏覽器使用單線程處理隊列中的事件和執行用戶代碼(也就是單線程;web workers除外)。
因此,瀏覽器每次只能處理這些任務中的一個,並且任意一個任務都能阻止其他任務的執行。
2 怎樣判斷代碼“足夠快”?0.1秒的用戶體驗為:用戶可以隨意操作,無需等待;0.2~1.0秒的延遲會被用戶注意到;如果超過1秒,那么用戶會覺得不流暢;超過10秒,用戶會非常沮喪。
手動代碼檢測:
<div onclick="jsTest">...</div>
function jsTest(){
var start = new Date().getMilliseconds();
//這里是一個開銷很大的代碼
var time = stop - start;
alert("jsTest() executes in " + time + " milliseconds");
}
fireBug的性能分析器
可以在測量的代碼中加入特定代碼來收集性能統計信息,或者在特定時間中實時檢驗具體執行的代碼來監視運行時間。后者分析的代買性能失真少,但獲取到的數據質量會第一點。你可以通過(點擊“發送”按鈕)
然后再星星firebug性能分析器查看耗時。
3 線程處理
使用多線程把開銷大的代碼從與用戶交互的線程中剝離開來。多線程的基本問題是不同的線程可以訪問並修改相同的地址。(我們需要的是一種像多線程那樣能多任務執行卻沒有線程之間互相侵入危險的方法)
4 Web Workers
讓我們來看一下如何利用Web Workers API 對值進行解封裝。如下展示了如何創建並啟動Worker:
//創建並開始執行worker
var worker = new Worker("js/decrypt.js");
//注冊事件處理程序,當worker給主線程發送信息時執行
worker.onmessage = function(e){
alert("The decrypted value is" + e.data);
}
//發送信息給worker,這里指待解密的值
worker.postMessage(getValueToDecrypt());
//下面為js/decrypt.js中的內容:
//注冊用來接收來自主線程信息的處理程序
onmessage = function(e){
//獲取傳過來的數據
var valueToDecrypt = e.data;
//TODO:這里實現解密功能
//把值返回給主線程
this.postMessage(decryptedValue);
}
在頁面上任何開銷很大的(例如,長時間運行)javascript操作都應委托給Worker;可以是運行速度更快。
5 如果你所使用的瀏覽器不支持Web Worker API ,那么可以用Gears Worker API ;代碼如下:
//創建worker Pool,它會產生Worker
var workerPool = google.gears.factory.create('beta.workpool');
//注冊事件處理程序,他接收來自Worker的信息
workerPool.onmessage = function(ignorel, ignorel2, e){
alert("The decrypted value is" + e.body);
}
//創建Worker
var workerId = workerPool.createWorkerFromUrl("js/decrypt.js");
//發送信息到這個Worker
workerPool.sendMessage(getValueToDecrpt(). workerId);
//下面是js/decrypt.js的Gears版本:
var workerPool = google.gears.workerPool;
workerPool.onmessage = function(ignorel, ignorel2, e){
//獲得傳遞過來的數據
var getValueToDecrpt = e.body;
//TODO:這里實現封裝功能
//把值返回給主線程
workerPool.sendMessage(decryptedValue, e.sender);
}
6. 定時器
var funState = {};
function expensiveOperation(){
var startTime = new Date().getMilliseconds();
while ((new Date().getMilliseconds() - startTime) < 80){
//TODO:它用如下方法執行開銷很大的運算:
//它在迭代的語塊中執行80毫秒內完成的工作,
//然后修改本函數外部"function"中的狀態。
}
if(!funState.isFinished){
//退出10秒后再執行expensiveOperation;
//用較大的值進行試驗,以在Ui響應和性能上取得合適的平衡
setTimeout(expensiveOperation(),10);
}
}
XHRHttpRequest: XHR 有同步與異步的執行模式。在異步模式中,XHR實質上就是一個擁有專用API的Web Worker。
XHR在在同步模式中,會導致用戶界面的持續延遲時間與XHR發送他的請求並解析來自服務端響應的整體耗時一樣。還會導致不可預知和用戶不能容忍的界面延遲。