【问题标题】:DOM Update slow in chrome than firefox looks like chrome has some rendering issueschrome 中的 DOM 更新比 firefox 慢 看起来 chrome 有一些渲染问题
【发布时间】:2014-04-23 22:25:57
【问题描述】:

我编写了一个代码,它在 DOM 中转储大量节点。当我在 firefox 中加载它时,它会在 2-3 秒 中呈现,但在 chrome (ver:33) 中它会冻结 UI 并且呈现需要 长时间(8-10秒)。

$.ajax({
    xhr: function () {
        var xhr = new window.XMLHttpRequest();
        xhr.addEventListener("progress", function (evt) {
            if (evt.lengthComputable) {
                var percentComplete = evt.loaded / evt.total * 100;
                $("#fetchProgress").attr("value", percentComplete);
            }
        }, false);
        return xhr;
    },
    type: 'GET',
    url: "/GetSomething",
    data: {},
    success: function (data) {
        ///process and dump to DOM//
        var fileLines = data.split('\n');
        var htmlString = '';
        for (var i = 0; i < fileLines.length; i++) {
            htmlString += '<span>' + (i + 1) + '. ' + fileLines[i]+</span>;
            if ((i % 1000) == 0) {
                $("#textPlace").append(htmlString);
                htmlString = '';
            }
        }
        fileLines = null;
        $("#textPlace").append(htmlString);
    }
});

我从互联网了解到 chrome 存在一些渲染错误,并尝试从该 URL 进行黑客攻击。 "Chrome Bug - window.scroll method intercepts DOM Rendering" 它开始工作,但现在又不工作了。请提出一些建议。 任何帮助表示赞赏。坦克大小提前致谢:)

【问题讨论】:

  • 你可以在服务器上格式化文件,然后只追加一次字符串
  • 尝试关闭 span 标签(例如:... + fileLines[i] + '&lt;/span&gt;';。这大大减少了我的简单测试用例的重新渲染时间。可能是因为 chrome 不需要修复损坏的 html。
  • @Yoshi:也试过关闭,但还没有改善。
  • 一个很小的变化:将$("#textPlace")移到for()之外,这样就不必一遍又一遍地查找元素。

标签: javascript jquery google-chrome firefox dom


【解决方案1】:

看看能不能避免append在这个函数下转html

            if ((i % 1000) == 0) {
                $("#textPlace").append(htmlString);
                htmlString = '';
            }

并且在代码的最后只有一个append。您想限制 DOM 操作 - 它通过触发多个浏览器重排来影响浏览器性能。

Google Dev: Speeding up JavaScript: Working with the DOM

从上面的链接中取出,您可以使用类似的东西来代替

var anchor, fragment = document.createDocumentFragment();
  for (var i = 0; i < 10; i ++) {
    anchor = document.createElement('a');
    anchor.innerHTML = 'test';
    fragment.appendChild(anchor);
  }
  element.appendChild(fragment);

【讨论】:

    【解决方案2】:

    如果我理解你的代码,你有一个数组,你想将它与 span 绑定在一起。您可以从代码中删除 for()(以及其中的模数 (=slow) ),从而节省大量时间:

    htmlString = '<span>'+ fileLines.join("</span><span>") +'</span>';
    

    这不会显示i 数字,但您可以切换到li 并使用数字而不是项目符号。


    这也可能有效:

    var fileLines = '<span>'+ data.replace('\n', '</span><span>') +'</span>';
    

    这有点混乱(这可能以&lt;/span&gt;&lt;span&gt;&lt;/span&gt; 结尾,你需要修剪\n 来解决这个问题(很容易做到)),但它不必将它变成一个数组,它应该加快速度

    【讨论】:

    • 感谢您的建议,但无论如何我们必须将大量节点撕裂并更新到 DOM 中。我还尝试了没有帮助的DOMFragement。为了查看生成这么多节点需要多少时间,我使用了 Mutation Observers ,但 chrome 更新视图的时间仍然是 firefox 的三倍。
    猜你喜欢
    • 2014-05-03
    • 1970-01-01
    • 2017-08-03
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    相关资源
    最近更新 更多