例如,假设我们有两个版本的lazyload(请参见下面的代码)。在性能方面,版本II是否优于版本I?
const imgs = document.querySelectorAll('img');
window.addEventListener('scroll' , lazyload);
// version I
function lazyload() {
imgs.forEach((img) => {
if (img.offsetTop < window.innerHeight + window.pageYOffset) {
img.src = img.dataset.src;
}
}
}
// version II
function lazyload() {
const innerHeight = window.innerHeight;
const pageYOffset = window.pageYOffset;
imgs.forEach((img) => {
if (img.offsetTop < innerHeight + pageYOffset) {
img.src = img.dataset.src;
}
}
答案 0 :(得分:0)
这似乎更好
// version III
function lazyload(){
const dimension = window.innerHeight + window.pageYOffset;
img.array.forEach(img => {
if (img.offsetTop < dimension) {
img.src = img.dataset.src;
}
});
}
答案 1 :(得分:0)
我将改述您的特定问题,如下所示:
访问
window.innerHeight
和/或window.pageYOffset
是否昂贵?
可以。根据{{3}}:
以下所有属性或方法(在JavaScript中要求/调用时)将触发浏览器同步计算样式和布局*。这也称为重排或Paul Irish of the Google Chrome Developer Tooling team,是常见的性能瓶颈。
...
窗口
window window.scrollX, window.scrollY window.innerHeight, window.innerWidth window.getMatchedCSSRules() only forces style
-layout thrashing(重点是我)
在What forces layout / reflow,Paul表示仅在某些情况下才会发生版面重排。下面的部分(我更加强调)比我能更好,更权威地回答您的问题。
- 仅当文档已更改且样式或布局无效时,重排才会产生成本。通常,这是因为DOM发生了更改(修改了类,添加/删除了节点,甚至添加了诸如:focus之类的伪类)。
- 如果强制布局,则必须首先重新计算样式。因此,强制布局会触发这两种操作。 他们的费用在很大程度上取决于内容/情况,但通常两种操作的费用都差不多。
- 您应该怎么做?好吧,下面的“关于强制布局的更多信息”部分详细介绍了所有内容,但
简短的版本是:
for
迫使布局和更改DOM的循环最糟糕,请避免使用。- 使用DevTools时间轴查看发生的情况。您可能会惊讶地发现您的应用程序代码和库代码经常遇到此问题。
- (通过bottom of that document或虚拟DOM实现)对DOM进行批量写入和读取。当数字仍然与上次进行布局时相同时,请在框架的开头(非常简单的rAF,滚动处理程序等)读取指标。
更改src
属性可能足以“使样式或布局无效”。 (尽管我怀疑使用FastDOM之类的东西会减轻或消除回流的成本。)
简而言之,您的“版本I”实现是可取的,据我所知,它没有真正的缺点。
如上所示,从窗口对象读取属性可能很昂贵。但其他人指出以下几点是正确的: