javascript - 长 html 绑定(bind)卡住浏览器

标签 javascript jquery html knockout.js

我正在使用 KnockoutJs html 属性绑定(bind)将一个大的 html 文档(约 2 兆)渲染到 DIV 元素中,如下所示:

<div id="myDiv" data-bind="with: $root.myDocument">
     <div id="elementBody"  data-bind="html: body">
     </div>
</div>

它工作得很好,但绑定(bind)时间大约需要 3-4 秒,同时用户浏览器卡住变得无法使用。

有没有办法渲染此文档,避免这么长的绑定(bind)时间?我可以逐步渲染它吗?

我尝试了什么

我尝试过这个自定义绑定(bind),但它似乎不是一个解决方案:

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 循环结束之前文档不可见。

最佳答案

原则上,您的 setTimeout 技术确实有助于为 DOM 提供时间来在添加 HTML 标记之间呈现内容。但是,您的绑定(bind)未正确编写以利用此功能:

    $.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 MB 的 DOM 内容已经很多了。我想知道你最终能多快得到它。

另一个可能会或可能不会缩短渲染时间的提示:在使用我建议的修复时,在渲染时将使用自定义绑定(bind)的元素设置为 display: none 。该修复应该有助于保持 dom (某种程度)响应,但大多数浏览器会在未显示正在更改的元素时优化 DOM 回流。如果这有效,您就可以消除我之前提到的批量附加的额外性能损失。

关于javascript - 长 html 绑定(bind)卡住浏览器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21550053/

相关文章:

javascript - 将单击列表的值传递给 EditForm 进行编辑

javascript - 如何在鼠标按下事件中更改类型复选框的 HTML 输入值

jQuery 使用淡入淡出效果更改图像 src

javascript - 处理在 iframe 内的新选项卡/窗口中打开

javascript - 为什么会发生这种换行?

javascript - 使用动态添加的表单(不是字段!)进行 BootstrapValidator 验证

javascript - 如何在可点击背景上将鼠标箭头变成手指指针?

javascript - 同位素 - 无法读取未定义的属性 'filteredItems'

java - 我想将 html 表数据转换为 pdf 并使用 jquery 下载它,代码如下

php - 比较两张表数据并显示不匹配和匹配数据