重新计算风格:为什么如此口吃?

时间:2013-11-05 18:26:09

标签: javascript css performance google-chrome

假设我们有一个代码将一系列类似的元素注入到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);

Demo

在Firefox(25.0)中运行此代码段时,调用“注入”和实际查看其结果的次数与“{1}}所记录的内容相对应的时间”。对于1000个元素,大约4毫秒; 10000,约40等。很正常,不是吗?

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

困惑,我已经针对不同场景检查了Chrome的分析器 - 结果发现瓶颈在于Recalculate Style动作。 10000个节点需要2-3秒,20000个节点需要8秒,30000个节点需要17秒。


现在真正的问题是:有没有人处于相同的情况,是否有任何解决方法?

我们想到的一种可能方式是将这些节点的可见性限制在一种懒惰的负载中('某种',因为它更多的是'懒惰显示':元素已经到位,只有它们的能见度有限)。事实证明,只有当元素即将变得可见时才会触发“重新计算样式”(实际上这是有意义的)。

1 个答案:

答案 0 :(得分:8)

使用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,但它已被修复。崩溃,不是速度

相关问题