2013-04-16 121 views
3

我想知道是否有一種方法來減少knockoutjs的Dom操作 - 我有一個大的可觀察數組,我看到在foreach中需要分配時間。基因敲除減少DOM操作

在調查了代碼並調試它之後,我發現淘汰賽將dom中的每個元素都放在了一起,而不是將所有元素放在一起。

是否有一種快速方法讓knockout在foreach語句中創建一個包含所有子節點的長字符串,然後將該字符串寫入DOM一次?

我的代碼:

self.items = ko.observableArray([]);  
function generateModel(data) { 
      var mapped = $.map(data, function (d) { return new item(d); }); 
      self.items(mapped); 
     } 

<!--ko foreach:{data:items}--> 
some template in here 
<!--/ko--> 

感謝。

回答

1

foreach綁定並不是在渲染大型陣列非常有效的。它旨在有效地處理動態數組(可能會以小方式進行修改)。

有一些解決方案,可以幫助你:

  1. 使用基於字符串的模板。一個example using Underscore is in the Knockout documentation

  2. 使用生成特定HTML內容的自定義綁定並將其添加到DOM。這種技術的一個例子是我的table binding

  3. 使用更快的foreach樣式綁定,如我的repeat binding

+0

嗨。感謝你的回答。我正在尋找一種方法來保存一個巨大的繩子,然後只給他加一次。在我的網站上,我看到了與大型數組的競爭 - 我通過從服務器分頁來減少數組,但你仍然會看到渲染需要很長時間。感謝您的回答 – Ram

+0

在淘汰賽中是否有一種方法可以使用多個模板引擎? – Ram

+0

我已經更新了Underscore示例以使用'templateEngine'選項,它支持這個選項:http://jsfiddle.net/6pStz/340/ –

1

是的,有使用油門擴展的方式:見文檔在http://knockoutjs.com/documentation/throttle-extender.html

+0

我不想延遲foreach語句(這就是我所知道的油門所做的) - 我不想推倒200個元素,我在observableArray中有200個追加到dom但是隻是在一個附加。 – Ram

+0

你試過了嗎?性能是否一樣? – nihique

+0

以及有多少物品導致您的問題?你真的需要渲染這個頁面上的所有項目,爲什麼不做某種虛擬渲染? – nihique

1

,如果你願意,你可以找到幾個很好的提示的位置: http://www.knockmeout.net/2012/04/knockoutjs-performance-gotcha.html

更妙的是,你可以在這裏找到一個有趣的實現自定義對象的所謂pauseableObservableArray(偉大的名字:)從巨大的開發商:rpniemeyer)http://jsfiddle.net/rniemeyer/fYnjG/

在這旁邊,對於第一個簡單的方法,你有沒有試圖從DOM元素刪除與一個if倉丁?

例如。 HTML:

<!-- ko ifnot: isWorking --> 
<div data-bind="foreach: blogs"> 
    <span data-bind="text: id"></span> 
</div> 

<!-- /ko --> 

視圖模型:

function BlogViewModel() { 
    var self = this; 
    self.blogs = ko.observableArray([{id:'qwe'}]); 

    self.isWorking= ko.observable(false); 


    self.populateBlogs = function() { 
     self.isWorking(true); 

     var tmp = self.blogs(); 

     for (var i = 0; i < 100000; i++) { 
      tmp.push({id:i}); 
     } 


     self.blogs(tmp); 
     self.isWorking(false); 
    } 


} 

[更新] 也許,如果你需要提高更多的渲染時間,你需要實現類似於在fiddle我建議實施的東西,或者實現一個自定義綁定處理器來「手工」完成所有的事情。

HTML:

<div data-bind="quickForEach: blogs"></div> 

viemodel: 例如,類似的東西

ko.bindingHandlers.quickForEach = { 

    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 

     var blogs = valueAccessor()(); 
     var innerText=''; 
     for (var i = 0; i < blogs.length; i++) { 
      //very dirty code!In production, concatenate strings in a smarter way 
      innerText += blogs[i].id; 
     } 
     $(element).text(innerText); 
    } 
}; 
+0

我會看看Michael Best建議的內容,並根據您在更新中提出的建議使用基於字符串的模板。謝謝 – Ram