重新计算风格:为什么这么口吃? [英] Recalculate Style: why so stuttering?

查看:139
本文介绍了重新计算风格:为什么这么口吃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

函数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个元素,约4ms;为10000,约40等。非常正常,不是吗?



但是,Chrome(30.0和Canary 32.0测试)并不是这样。虽然报告的处理和附加时间实际上少于Firefox的,但是这些元素的渲染需要更多LOT。



困惑,我已经检查了Chrome的分析器的不同情况 - 它发现瓶颈是在重新计算风格的行动。 10000个节点需要2-3秒,20000个节点需要8秒,30000个节点需要17秒。






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



我们想到的一种可能的方法是限制这些节点在一种延迟加载中的可见性('一种',因为它更多地关于'延迟显示':元素已经就位,只有它们的可见性受到限制)。它确认了重新计算风格只有当元素即将变为可见时(实际上是有意义的)才会触发。

解决方案

看起来像麻烦是 li 元素有 display:list-item



如果不是使用 ul / li



同时创建 li {display:block;}的css规则 code>修复延迟。



手动添加 list-item 元素已在DOM中呈现(


$ b
http://jsfiddle.net/6D7sM/1/



因此似乎chrome呈现速度缓慢 display:list-item 元素






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


Let's say we have a code that injects series of similar elements into the DOM. Something like this:

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.

When this snippet is run in Firefox (25.0), the time between calling 'inject' and actually seeing its results more-o-less corresponds to what is logged by time/timeEnd. For 1000 elements, about 4 ms; for 10000, about 40 and so on. Quite normal, ain't it?

It's very not so, however, with Chrome (30.0 and Canary 32.0 are tested). While the reported time for processing and appending is actually less than Firefox's, rendering of these elements takes a LOT more.

Puzzled, I've checked the Chrome's profiler for different scenarios - and it turned out the bottleneck is in Recalculate Style action. It takes 2-3 seconds for 10000 nodes, 8 seconds for 20000 nodes, and whopping 17 seconds for 30000 nodes.


Now the real question is: has anyone been in the same situation, are there any workarounds?

One possible way we've thought about is limiting the visibility of these nodes in a sort of lazy load ('a sort of', because it's more about 'lazy showing': the elements will already be in place, only their visibility will be limited). It's confirmed that 'Recalculate Style' is triggered only when element is about to become visible (which makes sense, actually).

解决方案

Looks like the trouble is with the li elements that have display:list-item

If instead of ul/li you use div elements it works pretty fast in chrome..

Also creating a css rule of li{display:block;} fixes the delay.

And manually adding the list-item shows the delay even if the elements are already rendered in the DOM (they have to be re-rendered ofcourse)

See demo at http://jsfiddle.net/6D7sM/1/

(so it seems that chrome is slow in rendering display:list-item elements)


There is also a relevant bug submission to chrome http://code.google.com/p/chromium/issues/detail?id=71305 which has been merged into http://code.google.com/p/chromium/issues/detail?id=%2094248 (looks like in earlier versions it was crashing chrome, but it has been fixed. the crashing, not the speed)

这篇关于重新计算风格:为什么这么口吃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆