2010-11-10 11 views
8

मेरे पास काफी लंबा चल रहा है (3 से 10 सेकेंड) फ़ंक्शन जो पृष्ठ के काफी कम इस्तेमाल किए गए हिस्से के लिए पृष्ठभूमि में डेटा लोड करता है। मेरे पास सवाल यह है कि निष्पादन के लिए इष्टतम चलने का समय और यह सुनिश्चित करने के लिए देरी का समय क्या है कि शेष पृष्ठ काफी इंटरैक्टिव रहता है, लेकिन डेटा को लोड करने से इसे तोड़ने में अत्यधिक देरी नहीं होती है?उत्तरदायी यूआई के लिए लंबे समय तक चलने वाले फ़ंक्शन को उप-विभाजित करने के लिए कितना?

उदाहरण के लिए:

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

आपको पता है कि किया जा रहा है जावास्क्रिप्ट (क्लाइंट-साइड) सीपीयू, स्मृति, मशीन कनेक्शन के नेटवर्क कनेक्शन, आदि में काफी हद तक। –

+1

@ जेसन मैकक्रीरी, ज़ाहिर है। यही कारण है कि मैं इस सवाल से पूछ रहा हूं और यह नहीं मानता कि इन नंबरों को निर्धारित करने का मेरा परीक्षण और त्रुटि विधि सुरक्षित है। – jball

उत्तर

3

किसी भी टाइमआउट मान लगभग 15ms से कम समकक्ष है - ब्राउज़र डोम अपडेट करेगा, और फिर टाइमआउट निष्पादित करेगा। अधिक जानकारी के लिए this और this देखें। मैं 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

0

1ms टाइमआउट वास्तव में 1 एमएस नहीं है। जब तक थ्रेड पैदा होता है, 1ms प्राप्त करने के लिए, यह शायद अधिक पैदा हुआ - क्योंकि ठेठ धागा समय-टुकड़ा 30 मिमी है। 1ms टाइमआउट के दौरान किसी भी अन्य धागे को निष्पादित किया जा सकता है, जिसका अर्थ यह हो सकता है कि 200 एमएमएस फिर से नियंत्रण प्राप्त करने से पहले चला गया।

क्यों न केवल 'doSomethingWithData' पूरी तरह से अलग थ्रेड में निष्पादित है?

+1

यह जावास्क्रिप्ट है: केवल एक धागा है। कम से कम, ब्राउज़र के साथ अभी केवल एक धागा है। –

+0

जब तक वेब श्रमिक आम नहीं होते हैं (9 0% ब्राउजर), मैं अपने जावास्क्रिप्ट को निष्पादित करने के लिए एक से अधिक धागे रखने पर गिनती नहीं कर रहा हूं। – jball

संबंधित मुद्दे