我确实理解requestAnimationFrame()
在运行不断更改样式属性的动画时非常有用。
const e = document.getElementById('e');
let count = 0;
function move(timestamp) {
e.style.left = ++count + 'px';
requestAnimationFrame(move);
};
requestAnimationFrame(move);
现在我的问题是:在requestAnimationFrame
中包装改变视图外观的所有内容是否有意义?
换句话说,这个伪代码示例会比没有requestAnimationFrame
的情况有更好的表现吗?
const e = document.getElementById('e');
let f = document.createDocumentFragment();
nodes.forEach((node, index) => {
f.appendChild(node);
}
requestAnimationFrame(timestamp => {
e.classList.toggle('active');
container.classList.add('active');
container.appendChild(fragment);
});
答案 0 :(得分:-1)
简短的回答是“使用rAF进行频繁更新”。在进行任何类型的DOM突变时,更重要的是将尽可能多的DOM批量转换为单个“事件循环”,以便允许浏览器尽可能少地重排/重绘。对于大多数一次性DOM突变,不需要使用rAF。但是,您可能不知道是否已经存在动画,在这种情况下,使用rAF允许浏览器确定执行DOM更新的最佳时间。以下是一些不良代码的示例(仅供参考):
let count = 10;
while(count--) setTimeout(() => {
const div = document.createElement('div');
document.body.appendChild(div)
});
每个超时都发生在一个单独的事件循环中,每个超时都在修改DOM。这可能会导致浏览器多次重排/重绘。要彻底改进这一点,您可以批量处理DOM更新,如下所示:
let c = 10;
const divs = [];
const doAppend = () => {
while(divs.length) document.body.appendChild(divs.shift())
};
while(c--) setTimeout(() => {
divs.push(document.createElement('div'));
if (++c === 9) doAppend();
});
如果你经常这样做,那就用rAF:
const doAppend = () => requestAnimationFrame(() => {
while(divs.length) document.body.appendChild(divs.shift())
});