重新计算风格:为什么如此结结巴巴
Recalculate Style: why so stuttering?
假设我们有一个代码,将一系列类似的元素注入到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 毫秒;对于 10000,大约 40 等等。很正常,不是吗?
然而,对于Chrome(30.0和Canary 32.0进行测试),情况并非如此。虽然报告的处理和追加时间实际上比 Firefox 少,但渲染这些元素需要更多。
感到困惑的是,我已经检查了Chrome的探查器以了解不同的场景 - 事实证明瓶颈在于"重新计算样式"操作。2 个节点需要 3-10000 秒,8 个节点需要 20000 秒,17 个节点需要 30000 个节点。
现在真正的问题是:是否有人遇到过同样的情况,有什么解决方法吗?
我们考虑的一种可能方法是在一种延迟加载中限制这些节点的可见性("一种",因为它更多的是关于"延迟显示":元素已经就位,只是它们的可见性将受到限制)。已确认"重新计算样式"仅在元素即将变得可见时才触发(这实际上是有道理的)。
看起来问题出在li
元素上,这些元素display:list-item
如果您不使用ul
/li
而是使用div
元素,则在chrome中可以快速运行。
此外,创建 css li{display:block;}
规则可以修复延迟。
手动添加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崩溃,但它已被修复。 崩溃,而不是速度)
- 为什么不't Javascript对我的输入值进行了一些重新检查
- 为什么“;未定义的“;在JavaScript中结束循环
- 为什么这在IE中的工作方式与在Firefox中不同
- 偶尔结结巴巴地说“;堆叠的”;translate()上的转换(v4.0.0-alpha40)
- 知道为什么我的旋转木马不会自动更改图片吗
- 为什么会出现错误;未捕获的类型错误:undefined不是函数;
- 为什么在单独的函数中应用时转换会闪烁/断断续续(D3)
- 为什么在变形之前不缺少Fx
- 为什么JavaScript在for循环为3时向所有4发出警报
- 为什么不是't窗口.恢复正常工作吗?(javascript/jquery)
- 为什么Airbnb风格指南说不鼓励依赖函数名称推断
- 为什么要使用0>javascript中的0
- 为什么无法在TypeScript中导出类实例
- 为什么grunt contrib connect的中间件选项的第三个参数是未定义的
- 为什么我的d3.jsselectAll+过滤器没有过滤
- 为什么HTML5拖放的目标是孩子?(可排序列表)
- 为什么忽略了eval()代码中的语法错误
- 为什么在画布上画线;t出现
- 为什么js事件消失了
- 重新计算风格:为什么如此结结巴巴