2010-11-10 48 views
8

我有一個相當長的運行(3到10秒)的功能,可以在頁面的相當不常使用的部分背景中加載數據。我的問題是,每次執行的最佳運行時間和延遲時間是多少,以確保頁面的其餘部分保持相當的交互性,但是數據的加載不會因分解而過度延遲?爲響應式UI細分多長時間運行的函數?

例如:

var i = 0; 
var chunkSize = 10; 
var timeout = 1; 
var data; //some array 

var bigFunction = function() { 
    var nextStop = chunkSize + i; //find next stop 
    if (nextStop > data.length) { nextStop = data.length } 

    for (; i < nextStop; i++) { 
     doSomethingWithData(data[i]); 
    } 
    if (i == data.length) { setTimeout(finalizingFunction, timeout); } 
    else { setTimeout(bigFunction , timeoutLengthInMs); }  
}; 

bigFunction(); //start it all off 

現在,我已經做了一些測試,和chunkSize能產生約100ms的執行時間和1ms的timeout似乎產生一個非常敏感的用戶界面,但我的一些例子」我看過推薦更大的塊(〜300毫秒)和更長的超時(20到100毫秒)。我是否在將我的功能切割成太多小塊時錯過了一些危險,或者試驗和錯誤是確定這些數字的安全方法?

+1

你知道那是JavaScript的(客戶端)的CPU,內存,網絡連接等因素大大增加。 – 2010-11-10 22:16:51

+1

@Jason McCreary,當然。這就是爲什麼我問這個問題,而不是假設我的試錯法確定這些數字是安全的。 – jball 2010-11-10 22:20:54

回答

3

任何小於15ms的超時值都是相等的 - 瀏覽器將更新DOM等,然後執行超時。有關更多信息,請參閱thisthis。我傾向於使用setTimeout(fn, 0)

我會檢查過去,而不是猜測的數字的時候,因爲賈森指出,會有客戶端之間的速度差異:

var data; // some array 
var i = 0; 
var MAX_ITERS = 20; // in case the system time gets set backwards, etc 
var CHECK_TIME_EVERY_N_ITERS = 3; // so that we don't check elapsed time excessively 
var TIMEOUT_EVERY_X_MS = 300; 

var bigFunction = function() { 
    var maxI = i + MAX_ITERS; 
    if (maxI > data.length) { maxI = data.length } 

    var nextTimeI; 
    var startTime = (new Date()).getTime(); // ms since 1970 
    var msElapsed; 

    while (i < maxI) { 
     nextTimeI = i + CHECK_TIME_EVERY_N_ITERS; 
     if (nextTimeI > data.length) { nextTimeI = data.length } 

     for (; i < nextTimeI; i++) { 
      doSomethingWithData(data[i]); 
     } 

     msElapsed = (new Date()).getTime() - startTime; 
     if (msElapsed > TIMEOUT_EVERY_X_MS) { 
      break; 
     } 
    } 

    if (i == data.length) { 
     setTimeout(finalizingFunction, 0); 
    } else { 
     setTimeout(bigFunction , 0); 
    } 
}; 

bigFunction(); //start it all off 
+0

我喜歡在實際客戶端計時的想法,但我想我會只需使用第一次運行就可以獲得每次迭代的大致平均時間,然後根據該時間將所有後續運行設置爲合理計數。 – jball 2010-11-18 06:10:32

0

1ms超時實際上不是1毫秒。當線程產生時,爲了達到1ms,它可能產生更多 - 因爲典型的線程時間片是30ms。在1ms超時期間可能會執行任意數量的其他線程,這可能意味着再次收到控制權之前200ms已經過去了。

爲什麼不只是在一個完全不同的線程中執行'doSomethingWithData'呢?

+1

這是javascript:只有一個線程。至少,現在瀏覽器只有一個線程。 – 2010-11-10 22:25:59

+0

直到網絡工作者普遍(90 +瀏覽器%),我不指望有多個線程來執行我的javascript。 – jball 2010-11-10 22:26:06