9

假设我们有一个将一系列相似元素注入 DOM 的代码。像这样的东西:

var COUNT = 10000,
    elements = Object.keys(Array(COUNT).join('|').split('|'));

var d = document, 
    root = d.getElementById('root');

function inject() {
    var count = COUNT,
        ul     = d.createElement('ul'),
        liTmpl = d.createElement('li'),
        liEl   = null;

    console.time('Processing elements');
    while (count--) {
        liEl = liTmpl.cloneNode(false);
        liEl.textContent = elements[count];
        ul.appendChild(liEl);
    }
    console.timeEnd('Processing elements');

    console.time('Appending into DOM');
    root.appendChild(ul);
    console.timeEnd('Appending into DOM');
};
d.getElementById('inject').addEventListener('click', inject);

演示

当此代码段在 Firefox (25.0) 中运行时,调用 'inject' 和实际看到更多结果之间的时间对应于time/timeEnd. 对于 1000 个元素,大约 4 ms;10000,大约 40 等等。很正常,不是吗?

然而,对于 Chrome(30.0 和 Canary 32.0 已测试),情况并非如此。虽然报告的处理和附加时间实际上少于 Firefox,但渲染这些元素需要更多时间。

困惑的是,我检查了 Chrome 的分析器是否有不同的场景——结果发现瓶颈在于重新计算样式操作。10000 个节点需要 2-3 秒,20000 个节点需要 8 秒,30000 个节点需要 17 秒。


现在真正的问题是:有没有人遇到过同样的情况,有什么解决方法吗?

我们考虑过的一种可能的方法是将这些节点的可见性限制在一种延迟加载中(“一种”,因为它更多的是关于“延迟显示”:元素已经到位,只有它们的可见性是有限的)。已确认仅当元素即将变得可见时才会触发“重新计算样式”(实际上这是有道理的)。

4

1 回答 1

10

看起来麻烦li在于具有display:list-item

如果不是ul/li您使用div元素,它在 chrome 中的运行速度非常快..

还创建一个li{display:block;}修复延迟的 CSS 规则。

list-item即使元素已经在 DOM 中渲染,手动添加显示延迟(当然必须重新渲染

请参阅http://jsfiddle.net/6D7sM/1/上的演示

所以看起来 chrome 渲染display:list-item元素的速度很慢)


还有一个相关的错误提交到 chrome http://code.google.com/p/chromium/issues/detail?id=71305已合并到http://code.google.com/p/chromium/issues /detail?id=%2094248看起来在早期版本中它正在崩溃 chrome,但它已被修复。崩溃,而不是速度

于 2013-11-05T18:56:03.283 回答