假设我们有一段代码将一系列相似的元素注入到 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 http://jsfiddle.net/6D7sM/.
当此代码片段在 Firefox (25.0) 中运行时,调用“inject”和实际看到其结果之间的时间或多或少对应于记录的内容time/timeEnd
。对于1000个元素,大约4毫秒; 10000,大约40等等。很正常,不是吗?
然而,对于 Chrome(30.0 和 Canary 32.0 已进行测试),情况并非如此。虽然报告的处理和附加时间实际上比 Firefox 少,但渲染这些元素需要更多时间。
困惑的是,我检查了 Chrome 的分析器是否有不同的场景 - 结果发现瓶颈在于重新计算样式操作。 10000 个节点需要 2-3 秒,20000 个节点需要 8 秒,30000 个节点则需要 17 秒。
现在真正的问题是:有人遇到过同样的情况吗?有解决方法吗?
我们考虑过的一种可能的方法是以某种延迟加载(“某种”,因为它更多的是“延迟显示”)来限制这些节点的可见性:元素已经就位,只有它们的可见性会被改变。有限的)。已确认仅当元素即将变得可见时才会触发“重新计算样式”(实际上这是有道理的)。