Knockout.js अर्ध-बड़े डेटासेट के तहत अविश्वसनीय रूप से धीमी गति से


86

मैं सिर्फ नॉकआउट के साथ शुरुआत कर रहा हूँ। (हमेशा इसे आज़माना चाहता था, लेकिन अब मेरे पास आखिरकार एक बहाना है!) - हालाँकि, मैं एक अपेक्षाकृत छोटे सेट के लिए एक टेबल बांधते समय कुछ बहुत खराब प्रदर्शन समस्याओं में भाग रहा हूं। डेटा (लगभग 400 पंक्तियों या तो)।

मेरे मॉडल में, मेरा निम्नलिखित कोड है:

this.projects = ko.observableArray( [] ); //Bind to empty array at startup

this.loadData = function (data) //Called when AJAX method returns
{
   for(var i = 0; i < data.length; i++)
   {
      this.projects.push(new ResultRow(data[i])); //<-- Bottleneck!
   }
};

मुद्दा यह है कि forऊपर वाला लूप लगभग 30 सेकंड या लगभग 400 पंक्तियों के साथ है। हालाँकि, अगर मैं कोड को इसमें बदल दूं:

this.loadData = function (data)
{
   var testArray = []; //<-- Plain ol' Javascript array
   for(var i = 0; i < data.length; i++)
   {
      testArray.push(new ResultRow(data[i]));
   }
};

फिर forलूप एक आंख की झपकी में पूरा होता है। दूसरे शब्दों में, pushनॉकआउट की observableArrayवस्तु की विधि अविश्वसनीय रूप से धीमी है।

यहाँ मेरा टेम्पलेट है:

<tbody data-bind="foreach: projects">
    <tr>
       <td data-bind="text: code"></td>
       <td><a data-bind="projlink: key, text: projname"></td>
       <td data-bind="text: request"></td>
       <td data-bind="text: stage"></td>
       <td data-bind="text: type"></td>
       <td data-bind="text: launch"></td>
       <td><a data-bind="mailto: ownerEmail, text: owner"></a></td>
    </tr>
</tbody>

मेरे सवाल:

  1. क्या यह मेरे डेटा (जो एक AJAX विधि से आता है) को एक नमूदार संग्रह में बाँधने का सही तरीका है?
  2. मुझे उम्मीद pushहै कि मैं हर बार कॉल करने के दौरान कुछ भारी फिर से कैल्क कर रहा हूं, जैसे कि बाध्य डोम ऑब्जेक्ट्स का पुनर्निर्माण करना। वहाँ एक रास्ता है या तो इस पुनर्गणना में देरी, या शायद एक ही बार में मेरे सभी मदों में धक्का?

यदि आवश्यक हो तो मैं और अधिक कोड जोड़ सकता हूं, लेकिन मुझे पूरा यकीन है कि यह प्रासंगिक है। अधिकांश भाग के लिए मैं साइट से नॉकआउट ट्यूटोरियल का अनुसरण कर रहा था।

अपडेट करें:

नीचे दी गई सलाह के अनुसार, मैंने अपना कोड अपडेट कर दिया है:

this.loadData = function (data)
{
   var mappedData = $.map(data, function (item) { return new ResultRow(item) });
   this.projects(mappedData);
};

हालांकि, this.projects()400 पंक्तियों के लिए अभी भी लगभग 10 सेकंड लगते हैं। मैं मानता हूं कि मुझे यकीन नहीं है कि यह नॉकआउट के बिना कितनी तेजी से होगा (सिर्फ डोम के माध्यम से पंक्तियों को जोड़ना), लेकिन मुझे लगता है कि यह 10 सेकंड से ज्यादा तेज होगा।

अद्यतन 2:

नीचे दी गई अन्य सलाह के अनुसार, मैंने jQuery.tmpl को एक शॉट दिया (जो कि मूल रूप से नॉकऑउट द्वारा समर्थित है), और यह अस्थायी इंजन केवल 3 सेकंड में लगभग 400 पंक्तियों को आकर्षित करेगा। यह सबसे अच्छा तरीका है, एक समाधान की कमी जैसा कि आप स्क्रॉल करते समय अधिक डेटा में लोड करेंगे।


1
क्या आप नॉकआउट फ़ॉरच बाइंडिंग का उपयोग कर रहे हैं या फ़ॉर्वर्ड बाइंडिंग फ़ॉरचेक। मैं सोच रहा हूँ कि क्या टेम्पलेट का उपयोग करके और jquery tmpl के बजाय देशी टेम्पलेट इंजन से फर्क पड़ सकता है।
madcapnmckay

1
@MikeChristensen - नॉकआउट में बाइंडिंग के साथ (foreach, with) जुड़ा हुआ अपना स्वयं का मूल टेम्पलेट इंजन है। यह अन्य टेम्पलेट इंजनों का भी समर्थन करता है, जिसका नाम jquery.tmpl है। अधिक जानकारी के लिए यहां पढ़ें । मैंने अलग-अलग इंजनों के साथ कोई बेंचमार्किंग नहीं की है, इसलिए नहीं पता कि यह मदद करेगा या नहीं। अपनी पिछली टिप्पणी को पढ़कर, IE7 में आप उस प्रदर्शन को प्राप्त करने के लिए संघर्ष कर सकते हैं जो आप बाद में हैं।
madcapnmckay

2
यह देखते हुए कि हमें कुछ महीने पहले IE7 मिला था, मुझे लगता है कि IE9 को गर्मियों, 2019 के आसपास रोल आउट किया जाएगा। ओह, हम सभी WinXP पर भी हैं .. Blech।
माइक क्रिस्टेन्सन

1
पीएस, कारण यह धीमी गति से लगता है कि आप 400 आइटम उस नमूदार सरणी को व्यक्तिगत रूप से जोड़ रहे हैं । अवलोकन के लिए हर परिवर्तन के लिए, उस सरणी पर निर्भर होने वाली किसी भी चीज़ के लिए दृश्य को पुन: प्रस्तुत करना होगा। जटिल टेम्प्लेट और कई वस्तुओं को जोड़ने के लिए, यह बहुत अधिक ओवरहेड है, जब आप इसे केवल एक ही बार में एक अलग उदाहरण पर सेट करके सरणी को अपडेट कर सकते थे। कम से कम तब, रेंडरिंग एक बार किया जाएगा।
जेफ मर्काडो

1
मुझे एक ऐसा रास्ता मिला जो तेज और साफ-सुथरा है (कुछ भी नहीं है)। valueHasMutatedइसका उपयोग करता है। अगर आपको समय मिला तो उत्तर की जाँच करें।
सुपर कूल

जवाबों:


16

जैसा कि टिप्पणियों में सुझाया गया है।

नॉकआउट में बाइंडिंग के साथ (फोरचेक,) के साथ जुड़ा हुआ अपना मूल टेम्पलेट इंजन है। यह अन्य टेम्पलेट इंजनों का भी समर्थन करता है, जिसका नाम jquery.tmpl है। अधिक जानकारी के लिए यहां पढ़ें । मैंने अलग-अलग इंजनों के साथ कोई बेंचमार्किंग नहीं की है, इसलिए नहीं पता कि यह मदद करेगा या नहीं। अपनी पिछली टिप्पणी को पढ़कर, IE7 में आप उस प्रदर्शन को प्राप्त करने के लिए संघर्ष कर सकते हैं जो आप बाद में हैं।

एक तरफ के रूप में, KO किसी भी js templating इंजन का समर्थन करता है, अगर किसी ने इसके लिए एडेप्टर लिखा है। आप दूसरों की कोशिश करना चाह सकते हैं क्योंकि jsRender द्वारा प्रतिस्थापित किए जाने के कारण jquery tmpl है ।


मैं बहुत बेहतर पूर्ण jquery.tmplहो रहा हूँ इसलिए मैं इसका उपयोग करूँगा। अगर मेरे पास कुछ अतिरिक्त समय है, तो मैं अन्य इंजनों की जांच करने के साथ-साथ खुद भी लिख सकता हूं। धन्यवाद!
माइक क्रिस्टेन्सन

1
@MikeChristensen - क्या आप अभी भी data-bindअपने jQuery टेम्पलेट में स्टेटमेंट का उपयोग कर रहे हैं, या आप $ {code} सिंटैक्स का उपयोग कर रहे हैं?
इरिकब

@ericb - नए कोड के साथ, मैं ${code}सिंटैक्स का उपयोग कर रहा हूं और यह बहुत तेज है। मैं भी काम करने के लिए अंडरस्कोर पाने की कोशिश कर रहा हूँ। लेकिन अभी तक कोई भाग्य नहीं मिला है ( <% .. %>सिंटैक्स ASP.NET के साथ हस्तक्षेप करता है), और वहाँ अभी तक JsRender समर्थन प्रतीत नहीं होता है।
माइक क्रिस्टेंसन

1
@MikeChristensen - ठीक है, तो यह समझ में आता है। KO का मूल टेम्पलेट इंजन जरूरी नहीं है कि अक्षम हो। जब आप $ {code} सिंटैक्स का उपयोग करते हैं, तो आपको उन तत्वों पर कोई डेटा-बाइंडिंग नहीं मिलती है (जो पूर्ण सुधार करता है)। इस प्रकार यदि आप एक की संपत्ति को बदलते हैं ResultRow, तो यह यूआई को अपडेट नहीं करेगा (आपको projectsअवलोकन योग्य एरे को अपडेट करना होगा जो आपकी तालिका के पुन: प्रतिपादन के लिए मजबूर करेगा)। $ {} निश्चित रूप से लाभप्रद हो सकता है यदि आपका डेटा केवल बहुत अधिक पढ़ा गया हो
ericb

4
काला जादू! jquery.tmpl अब विकास में नहीं है
एलेक्स लारजेरे

50

कृपया देखें: नॉकआउट। जेएस का प्रदर्शन गोत्र # 2 - अवलोकनीय है

एक बेहतर पैटर्न हमारे अंतर्निहित सरणी का संदर्भ प्राप्त करना है, इसे पुश करना है, फिर .valueHasMutated () कॉल करें। अब, हमारे ग्राहकों को केवल एक सूचना प्राप्त होगी जो दर्शाती है कि सरणी बदल गई है।


13

$ .Map का उपयोग करने के अलावा KO के साथ पृष्ठांकन का उपयोग करें

मुझे 1400 रिकॉर्ड के बड़े डेटासेट के साथ एक ही समस्या थी जब तक कि मैं नॉकआउट के साथ पेजिंग नहीं करता था। $.mapरिकॉर्ड्स को लोड करने के लिए उपयोग करने से बहुत फर्क पड़ा लेकिन DOM रेंडर का समय अभी भी छुपा हुआ था। तब मैंने पृष्ठांकन का उपयोग करने का प्रयास किया और इससे मेरे डेटासेट की रोशनी तेजी से और साथ ही उपयोगकर्ता के अनुकूल हो गई। 50 के पृष्ठ आकार ने डाटासेट को बहुत कम कर दिया और DOM तत्वों की संख्या को नाटकीय रूप से कम कर दिया।

KO के साथ करना बहुत आसान है:

http://jsfiddle.net/rniemeyer/5Xr2X/


11

नॉकआउट जेएस में कुछ महान ट्यूटोरियल हैं, विशेष रूप से डेटा को लोड करने और सहेजने के बारे में

उनके मामले में, वे डेटा का उपयोग करते हैं getJSON()जो बेहद तेज है। उनके उदाहरण से:

function TaskListViewModel() {
    // ... leave the existing code unchanged ...

    // Load initial state from server, convert it to Task instances, then populate self.tasks
    $.getJSON("/tasks", function(allData) {
        var mappedTasks = $.map(allData, function(item) { return new Task(item) });
        self.tasks(mappedTasks);
    });    
}

1
निश्चित रूप से एक बड़ा सुधार है, लेकिन self.tasks(mappedTasks)चलाने में लगभग 400 सेकंड (400 पंक्तियों के साथ) लगता है। मुझे लगता है कि यह अभी भी स्वीकार्य नहीं है।
माइक क्रिस्टेंसन

मैं मानता हूँ कि 10 सेकंड स्वीकार्य नहीं है। नॉकआउट का उपयोग करते हुए, मुझे यकीन नहीं है कि नक्शे से बेहतर क्या है, इसलिए मैं इस प्रश्न को पसंद करूंगा और बेहतर उत्तर के लिए देखूंगा।
डेल्ट्री

1
ठीक। उत्तर निश्चित रूप से +1मेरे कोड को सरल बनाने और नाटकीय रूप से गति बढ़ाने दोनों के लिए योग्य है । शायद किसी को अधिक विस्तृत विवरण है कि अड़चन क्या है।
माइक क्रिस्टेन्सन

9

कोग्रिड को एक रूप दें । यह होशियारी से आपके पंक्ति प्रतिपादन का प्रबंधन करता है ताकि यह अधिक प्रदर्शनकारी हो।

यदि आप एक foreachबाध्यकारी का उपयोग करके 400 पंक्तियों को एक मेज पर बांधने की कोशिश कर रहे हैं , तो आपको केओ के माध्यम से डोम में धकेलने में परेशानी होगी।

KO foreachबाइंडिंग का उपयोग करते हुए कुछ बहुत ही दिलचस्प चीजें करते हैं , जिनमें से अधिकांश बहुत अच्छे संचालन हैं, लेकिन वे आपके पूर्ण आकार के बढ़ने के साथ-साथ टूटने लगते हैं।

मैं बड़े डेटा-सेट्स को टेबल / ग्रिड से बांधने की कोशिश की लंबी अंधेरी सड़क के नीचे रहा हूं, और आप स्थानीय स्तर पर डेटा को अलग करने / पृष्ठ को तोड़ने की आवश्यकता को समाप्त करते हैं।

KoGrid यह सब करता है। इसका निर्माण केवल उन पंक्तियों को प्रस्तुत करने के लिए किया गया है जो दर्शक पृष्ठ पर देख सकते हैं, और तब तक अन्य पंक्तियों को वर्चुअलाइज कर सकते हैं जब तक कि वे आवश्यक न हों। मुझे लगता है कि आप अपने अनुभव से 400 से अधिक वस्तुओं पर अपनी पूर्णता पाएंगे।


1
यह IE7 (पूरी तरह से नमूने के काम में से कोई भी) पर पूरी तरह से टूटा हुआ प्रतीत होता है, अन्यथा यह बहुत अच्छा होगा!
माइक क्रिस्टेंसन

इस पर गौर करना - KoGrid अभी भी सक्रिय विकास में है। हालांकि, यह कम से कम अपने सवाल का जवाब देता है?
एर

1
हाँ! यह मेरे मूल संदेह की पुष्टि करता है कि डिफ़ॉल्ट KO टेम्पलेट इंजन काफी धीमा है। यदि आप किसी को भी आपके लिए गिनी पिग KoGrid गिनी की जरूरत है, मुझे खुशी होगी। जैसा हम चाहते हैं वैसा ही लगता है!
माइक क्रिस्टेंसन

अरे। यह वास्तव में अच्छा लग रहा है! दुर्भाग्य से, मेरे एप्लिकेशन के 50% से अधिक उपयोगकर्ता IE7 का उपयोग करते हैं!
जिम जी।

दिलचस्प है, आजकल हमें अनिच्छा से IE11 का समर्थन करना है। पिछले 7 साल में हालात सुधरे हैं।
MrBoJangles

5

बहुत बड़े सरणी को प्रस्तुत करने पर ब्राउज़र को लॉक करने से बचने का एक उपाय यह है कि सरणी को ऐसे 'थ्रॉटल' करें कि बीच में एक नींद के साथ केवल कुछ तत्व एक बार में जुड़ जाएं। यहाँ एक समारोह है जो सिर्फ इतना ही करेगा:

function throttledArray(getData) {
    var showingDataO = ko.observableArray(),
        showingData = [],
        sourceData = [];
    ko.computed(function () {
        var data = getData();
        if ( Math.abs(sourceData.length - data.length) / sourceData.length > 0.5 ) {
            showingData = [];
            sourceData = data;
            (function load() {
                if ( data == sourceData && showingData.length != data.length ) {
                    showingData = showingData.concat( data.slice(showingData.length, showingData.length + 20) );
                    showingDataO(showingData);
                    setTimeout(load, 500);
                }
            })();
        } else {
            showingDataO(showingData = sourceData = data);
        }
    });
    return showingDataO;
}

आपके उपयोग के मामले के आधार पर, इससे बड़े पैमाने पर UX सुधार हो सकता है, क्योंकि उपयोगकर्ता केवल स्क्रॉल करने से पहले पंक्तियों के पहले बैच को देख सकता है।


मुझे यह समाधान पसंद है, लेकिन हर पुनरावृत्ति को सेटटाउट करने के बजाय, मैं हर 20 या अधिक पुनरावृत्तियों में केवल सेटटाइमआउट चलाने की सलाह देता हूं क्योंकि हर बार लोड करने में बहुत लंबा समय लगता है। मैं देखता हूं कि आप ऐसा कर रहे हैं +20 के साथ, लेकिन यह पहली नज़र में मेरे लिए स्पष्ट नहीं था।
charlierlee

5

परिवर्तन का लाभ उठाते हुए () परिवर्तनशील तर्कों को स्वीकार करते हुए मेरे मामले में सर्वश्रेष्ठ प्रदर्शन दिया। 1300 पंक्तियाँ 5973ms (~ 6 सेकंड) के लिए लोड हो रही थीं। इस अनुकूलन के साथ लोड समय 914ms (<1 सेकंड) तक नीचे था,
जो कि 84.7% सुधार है!

अधिक जानकारी के लिए एक नमूदारअरे में आइटम धक्का

this.projects = ko.observableArray( [] ); //Bind to empty array at startup

this.loadData = function (data) //Called when AJAX method returns
{
   var arrMappedData = ko.utils.arrayMap(data, function (item) {
       return new ResultRow(item);
   });
   //take advantage of push accepting variable arguments
   this.projects.push.apply(this.projects, arrMappedData);
};

4

मैं डेटा के ऐसे विशाल संस्करणों के साथ काम कर रहा था जो मेरे लिए valueHasMutatedएक आकर्षण की तरह काम कर रहे थे।

देखें मॉडल:

this.projects([]); //make observableArray empty --(1)

var mutatedArray = this.projects(); -- (2)

this.loadData = function (data) //Called when AJAX method returns
{
ko.utils.arrayForEach(data,function(item){
    mutatedArray.push(new ResultRow(item)); -- (3) // push to the array(normal array)  
});  
};
 this.projects.valueHasMutated(); -- (4) 

कॉलिंग के बाद (4)सरणी डेटा को आवश्यक अवलोकन योग्य लोड किया जाएगा जो कि हैthis.projects रूप से ।

अगर आपको समय मिला है तो इस पर ध्यान दें और किसी भी परेशानी के बारे में मुझे बताएं

यहां ट्रिक: इस तरह से, अगर किसी भी निर्भरता (गणना, सब्सक्राइबर आदि) के मामले में पुश स्तर पर बचा जा सकता है और हम कॉल करने के बाद उन्हें एक बार में निष्पादित कर सकते हैं (4)


1
समस्या बहुत अधिक कॉल करने की नहीं है push, समस्या यह है कि पुश करने के लिए एक भी कॉल लंबे समय के रेंडर का कारण होगा। यदि किसी सरणी में 1000 आइटम हैं foreach, तो किसी एक आइटम को पूरे फ़ॉरच्यूअर पर धकेलने और आप एक बड़ी रेंडर समय लागत का भुगतान करते हैं।
थोड़ा

1

JQuery.tmpl का उपयोग करने के साथ संयोजन में एक संभव कार्य-आस-पास, एक बार में वस्तुओं को एक अतुल्यकालिक तरीके से अवलोकन करने के लिए सेटटाउट का उपयोग करके धक्का देना है;

var self = this,
    remaining = data.length;

add(); // Start adding items

function add() {
  self.projects.push(data[data.length - remaining]);

  remaining -= 1;

  if (remaining > 0) {
    setTimeout(add, 10); // Schedule adding any remaining items
  }
}

इस तरह, जब आप एक बार में केवल एक ही आइटम जोड़ते हैं, तो ब्राउज़र / नॉकआउट.जेएस डोम के अनुसार हेरफेर करने के लिए अपना समय ले सकता है, बिना ब्राउज़र को कई सेकंड के लिए पूरी तरह से अवरुद्ध किया जा सकता है, ताकि उपयोगकर्ता सूची को एक साथ स्क्रॉल कर सके।


2
यह एन संख्या को DOM अपडेट के लिए बाध्य करेगा जिसके परिणामस्वरूप कुल रेंडरिंग समय होगा जो एक बार में सब कुछ करने से बहुत लंबा है।
फ्रेड्रिक सी

यह निश्चित रूप से सही है। हालाँकि, बात यह है कि N के एक बड़ी संख्या के संयोजन और एक आइटम को प्रोजेक्ट सरणी में धकेलने से अन्य DOM अद्यतनों या संगणनाओं की एक महत्वपूर्ण मात्रा को ट्रिगर किया जा सकता है, जिससे ब्राउज़र फ्रीज़ हो सकता है और आपको टैब को मारने की पेशकश कर सकता है। टाइमआउट होने से, प्रति आइटम या प्रति 10, 100 या कुछ अन्य मदों के अनुसार, ब्राउज़र अभी भी उत्तरदायी होगा।
गनाब।

2
मैं कहूंगा कि यह सामान्य मामले में गलत दृष्टिकोण है जहां कुल अपडेट ब्राउज़र को फ्रीज नहीं करेगा, लेकिन जब सभी विफल हो जाते हैं तो इसका उपयोग करना होता है। मेरे लिए यह एक बुरी तरह से लिखे गए अनुप्रयोग की तरह लगता है जहां प्रदर्शन के मुद्दों को हल करने के बजाय इसे फ्रीज नहीं करना चाहिए।
फ्रेड्रिक सी

1
बेशक यह सामान्य मामले में गलत दृष्टिकोण है, इसमें कोई भी आपसे असहमत नहीं होगा। यदि आप DOM ऑपरेशंस का लोड करना चाहते हैं, तो ब्राउज़र फ्रीज़ को रोकने के लिए यह हैक और प्रूफ-ऑफ-कॉन्सेप्ट है। जब सेल प्रति कई बाइंडिंग के साथ कई बड़े HTML तालिकाओं को सूचीबद्ध करता है, तो मुझे कुछ साल पहले इसकी आवश्यकता होती है, जिसके परिणामस्वरूप हजारों बाइंडिंग का मूल्यांकन किया जाता है, प्रत्येक DOM की स्थिति को प्रभावित करता है। वेब एप्लिकेशन के रूप में एक्सेल-आधारित डेस्कटॉप एप्लिकेशन के पुन: कार्यान्वयन की शुद्धता की पुष्टि के लिए, कार्यक्षमता की अस्थायी रूप से आवश्यकता थी। फिर इस समाधान ने पूरी तरह से काम किया।
gnab

टिप्पणी ज्यादातर दूसरों को यह मानने के लिए नहीं पढ़ने के लिए थी कि यह पसंदीदा तरीका था। मैंने मान लिया कि आप जानते हैं कि आप क्या कर रहे थे।
फ्रेड्रिक सी

1

मैं प्रदर्शन के साथ प्रयोग कर रहा हूं, और दो योगदान हैं जो मुझे आशा है कि उपयोगी हो सकते हैं।

मेरे प्रयोग डोम हेरफेर समय पर ध्यान केंद्रित करते हैं। इसलिए इसमें जाने से पहले, यह एक निश्चित सारणी बनाने से पहले एक जेएस सरणी में धकेलने के बारे में ऊपर दिए गए बिंदुओं का पालन करने के लिए निश्चित रूप से लायक है।

लेकिन अगर डोम हेरफेर समय अभी भी आपके रास्ते में हो रहा है, तो इससे मदद मिल सकती है:


1: धीमी रेंडर के आसपास एक लोडिंग स्पिनर को लपेटने के लिए एक पैटर्न, फिर आफ्टररेंडर का उपयोग करके इसे छिपाएं

http://jsfiddle.net/HBYyL/1/

यह वास्तव में प्रदर्शन की समस्या के लिए ठीक नहीं है, लेकिन यह दर्शाता है कि एक देरी संभवतः अपरिहार्य है यदि आप हजारों वस्तुओं पर लूप करते हैं और यह एक पैटर्न का उपयोग करता है जहां आप सुनिश्चित कर सकते हैं कि आपके पास लोडिंग स्पिनर है, जो लंबे समय तक केओ ऑपरेशन से पहले दिखाई देता है, फिर छिपाना बाद में। तो यह कम से कम यूएक्स में सुधार करता है।

सुनिश्चित करें कि आप एक स्पिनर को लोड कर सकते हैं:

// Show the spinner immediately...
$("#spinner").show();

// ... by using a timeout around the operation that causes the slow render.
window.setTimeout(function() {
    ko.applyBindings(vm)  
}, 1)

स्पिनर छिपाएँ:

<div data-bind="template: {afterRender: hide}">

कौन से ट्रिगर:

hide = function() {
    $("#spinner").hide()
}

2: html बाइंडिंग को हैक के रूप में उपयोग करना

मुझे एक पुरानी तकनीक याद थी जब मैं ओपेरा के साथ सेट टॉप बॉक्स पर काम कर रहा था, डोम हेरफेर का उपयोग करके यूआई का निर्माण कर रहा था। यह धीमी गति से भयावह था, इसलिए समाधान एचटीएमएल के बड़े हिस्से को तार के रूप में संग्रहीत करना था, और इनर HTML संपत्ति सेट करके तारों को लोड करना था।

HTML बाइंडिंग का उपयोग करके कुछ ऐसा ही हासिल किया जा सकता है और एक गणना जो HTML को पाठ के एक बड़े भाग के रूप में व्युत्पन्न करता है, फिर इसे एक बार में लागू करता है। यह प्रदर्शन समस्या को ठीक करता है, लेकिन बड़े पैमाने पर नकारात्मक पक्ष यह है कि यह गंभीर रूप से सीमित करता है कि आप प्रत्येक तालिका पंक्ति के अंदर बाध्यकारी के साथ क्या कर सकते हैं।

यहां एक ऐसा बेड़ा है जो इस दृष्टिकोण को दिखाता है, एक फ़ंक्शन के साथ जिसे तालिका पंक्तियों के अंदर से किसी आइटम को अस्पष्ट रूप से हटाने के लिए कहा जा सकता है। स्पष्ट रूप से यह उचित KO जितना अच्छा नहीं है, लेकिन अगर आपको वास्तव में धमाकेदार (ish) प्रदर्शन की आवश्यकता है, तो यह एक संभावित समाधान है।

http://jsfiddle.net/9ZF3g/5/


1

IE का उपयोग करते समय, देव टूल्स को बंद करने का प्रयास करें।

IE में डेवलपर टूल खुले होने से यह ऑपरेशन धीमा हो जाता है। मैं एक सरणी में ~ 1000 तत्व जोड़ रहा हूं। जब देव उपकरण खुले होते हैं, तो ऐसा होने में लगभग 10 सेकंड लगते हैं और IE जम जाता है। जब मैं देव उपकरण बंद करता हूं, तो ऑपरेशन तत्काल होता है और मुझे IE में कोई धीमा नहीं दिखता है।


0

मैंने यह भी देखा कि आईओ में नॉकआउट जेएस टेम्पलेट इंजन धीमी गति से काम करता है, मैंने इसे अंडरस्कोर।जेएस के साथ बदल दिया, तेजी से काम करता है।


आपने यह कैसे किया कृपया?
स्टु हार्पर

@StuHarper मैं अंडरस्कोर पुस्तकालय और फिर आयातित main.js में मैं कदम की अंडरस्कोर एकीकरण अनुभाग में वर्णित पीछा knockoutjs.com/documentation/template-binding.html
मार्सेलो

IE के किस संस्करण में यह सुधार हुआ?
bkwdesign

@bkdesign I मैं IE 10, 11.
Marcello
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.