从窗口对象读取属性是否昂贵?

时间:2019-04-21 00:59:42

标签: javascript web-performance

例如,假设我们有两个版本的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; 
  }
}

2 个答案:

答案 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之类的伪类)。
  •   
  • 如果强制布局,则必须首先重新计算样式。因此,强制布局会触发这两种操作。 他们的费用在很大程度上取决于内容/情况,但通常两种操作的费用都差不多。
  •   
  • 您应该怎么做?好吧,下面的“关于强制布局的更多信息”部分详细介绍了所有内容,但
      简短的版本是:      
        
    1. for 迫使布局和更改DOM的循环最糟糕,请避免使用。
    2.   
    3. 使用DevTools时间轴查看发生的情况。您可能会惊讶地发现您的应用程序代码和库代码经常遇到此问题。
    4.   
    5. (通过bottom of that document或虚拟DOM实现)对DOM进行批量写入和读取。当数字仍然与上次进行布局时相同时,请在框架的开头(非常简单的rAF,滚动处理程序等)读取指标。
    6.   
  •   

更改src属性可能足以“使样式或布局无效”。 (尽管我怀疑使用FastDOM之类的东西会减轻或消除回流的成本。)

简而言之,您的“版本I”实现是可取的,据我所知,它没有真正的缺点。

您的一般问题

如上所示,从窗口对象读取属性可能很昂贵。但其他人指出以下几点是正确的:

  1. 过早或过分地进行优化可能会花费您宝贵的时间,精力和(取决于您的解决方案)可维护性。
  2. 确定的唯一方法是测试。尝试两种版本的代码,并仔细分析您喜欢的开发工具的输出以了解性能差异。