先前寫過一個遮罩的功能,可以讓PG呼叫遮罩,然後進行AJAX處理
讓使用者等待畫面處理完成!
最近有人反應,他們使用後發現,部份的頁面會產生延遲顯示的狀況!!
也就是遮罩不會馬上顯示~
便開始追查問題
首先先用chrome來進行Timeline的錄製
發現當我按下儲存的時侯(click事件)
畫面就停住了,便產生了大量的GC javascript Heap高達 94MB
所以針對程式一看~
嗯,事出必有因,畫面的行為如下:
1、畫面上有近1000個checkbox
2、當按下送出的時侯會針對checkbox 進行取值,有選取的就加入陣例(透過Each的方式)
想了一下,這應該是因為進行了javascript的大量運算,所以遮罩完全跑不出來 UI的Thread就停了
所以便寫了一個測試程式:
1、產生一個簡單的For計算,j++
var j = 0;
for (var i = 0; i < 1000000000; i++) {//讓JS產生一個大量運算
j++;
}
console.log(j);
2、透過Deferred 物件,保證執行完成
var dtd = $.Deferred(); // 新建deferred
3、透過setTimeout 讓畫面延遲5秒,直到動畫完成
setTimeout(tasks, 5000); // 停頓5秒
這邊可能有人覺得奇怪,為何還要設定SetTimeout 5秒後才執行程式
我們已經使用了Deferred的物件了,應該可以保證事件執行完成
但是經過測試,我們確實是保證物件有執行了,但~因為我們後續馬上執行了一個大量運算
其實是會導致Browser偵測到一個JS佔用到太多CPU,而產生停止的訊息,所以導致動畫也無法完整執行完畢
失敗
成功
附上檔案
我們已經使用了Deferred的物件了,應該可以保證事件執行完成
但是經過測試,我們確實是保證物件有執行了,但~因為我們後續馬上執行了一個大量運算
其實是會導致Browser偵測到一個JS佔用到太多CPU,而產生停止的訊息,所以導致動畫也無法完整執行完畢
失敗
var dtd = $.Deferred(); // 新建deferred
var show = function (dtd) {
var tasks = function () { //裡面請放置你的主程式!
funOpenLoadingMask(true);
dtd.resolve(); // deferred的狀態改變
};
tasks();
return dtd.promise();
};
$.when(show(dtd))
.then(function () {
var j = 0;
for (var i = 0; i < 1000000000; i++) {//讓JS產生一個大量運算
j++;
}
console.log(j);
}).done(funOpenLoadingMask(false))
成功
var show = function (dtd) {
funOpenLoadingMask(true);
var tasks = function () { //裡面請放置你的主程式!
var j = 0;
for (var i = 0; i < 1000000000; i++) {//讓JS產生一個大量運算
j++;
}
console.log(j);
dtd.resolve(); // deferred的狀態改變
};
setTimeout(tasks, 5000); // 停頓5秒
return dtd.promise();
};
$.when(show(dtd))
.then(function () {
funOpenLoadingMask(false);
});
附上檔案