我使用KnockoutJs html属性绑定将一个大型html文档(~2 mega)呈现为如下所示的DIV元素:
<div id="myDiv" data-bind="with: $root.myDocument">
<div id="elementBody" data-bind="html: body">
</div>
</div>它工作得很好,但是绑定时间大约需要3-4秒,而用户浏览器会结冰,变得不可用。
是否有一种方法可以使本文档避免如此长的绑定时间?我可以逐步渲染吗?
我试过的
我尝试使用这种自定义绑定,但它似乎不是一个解决方案:
ko.bindingHandlers.appendText = {
init: function (element, valueAccessor, allBindings) {
var data = ko.utils.unwrapObservable(valueAccessor());
var array = data.match(/.{1,1000}/g);
$.each(array, function (i, val) {
setTimeout(function () {
$(element).append(array[i]);
}, 5);
});
}
};它破坏标记,在.each循环结束之前文档不可见。
发布于 2014-02-04 15:52:37
原则上,您的setTimeout技术确实有助于给DOM时间在添加HTML标记之间呈现内容。但是,您的绑定没有正确地编写以利用这一点:
$.each(array, function (i, val) {
setTimeout(function () {
$(element).append(array[i]);
}, 5);
});这样做时,它会在所有数组项上“同步”循环,同时添加不同的setTimeout调用。你可能想要做的是,做第一个附加,然后setTimeout做第二个附加,然后setTimeout做第三个附加,等等。
// replacing your foreach loop
var $element = $(element),
appendItem = function (index) {
if (index < array.length) {
$(element).append(array[index]);
setTimeout(function () {
appendItem(++index);
}, 1);
});
};
appendItem(0);这应该会触发添加标记之间的呈现(还没有测试代码,如果代码中有错误,很抱歉)。但是,这可能会使整个过程变得更慢,如果您从开始到结束测量它,因为现在将会(可能)有一堆DOM重绘。不过你可以试一试。
真正的问题是,你能期待什么?2 MBs的DOM内容是很多。我想知道你最终能有多快得到它。
还有一个可能或不可能改善呈现时间的提示:在使用我建议的修复时,在呈现时设置使用自定义绑定到display: none的元素。修复应该有助于保持dom (某种程度上的)响应,但是大多数浏览器将在未显示正在更改的元素时优化DOM重构。如果这样做有效,您可以取消我前面提到的批处理附加的额外性能损失。
https://stackoverflow.com/questions/21550053
复制相似问题