最佳实践:替换每个元素还是仅检查和替换已更改的内容是否更有效?

时间:2018-07-07 01:36:15

标签: javascript

这个问题源于我在Javascript中面临的难题,尽管更一般的科学回答将非常有帮助。

如果要迭代对象或数组以用于其他目的-并且已知只有一个感兴趣的元素发生了变化,可以对其进行操作,则最好:

  • 用新数据替换每个元素以反映更改

  • 严格检查每个元素,仅替换已更改的元素

(在此示例中,虽然只有一个文本信息旨在更改,但是图形的所有条形的高度都是相对的,尽管它们是相对的。)

Array.from(result['data']).forEach(row => {
    const bar = document.getElementById('bar-' + row['date']);
    bar.style.height = 'calc(1.6rem + ' + row['percentage'] + '%)';
    bar.firstChild.textContent = row['distance'];
});

或者:

Array.from(result['data']).forEach(row => {
    const bar = document.getElementById('bar-' + row['date']);
    bar.style.height = 'calc(1.6rem + ' + row['percentage'] + '%)';
    if (bar.firstChild.textContent !== row['distance']) bar.firstChild.textContent = row['distance'];
});

我认为这是一个暴露我无知的问题,这使我很难研究一个结论:当已知某个差异存在于集合中的某个位置时,替换所有元素是否需要更多的计算工作?更便宜地找出有问题的个人并仅更改该值?

(事实证明,设置计时器(即console.timeEnd())没有定论。)

任何教育都会受到赞赏。我无法解决这个问题。

3 个答案:

答案 0 :(得分:2)

这取决于浏览器。

至少在Chrome和Opera上,未经检查的普通分配看起来比查找现有文本的性能更高,即使在查找现有文本的基础上也没有可能的分配,其数量级约为3倍:

(警告:运行以下代码会在一段时间内阻止您的浏览器,只有在确定时才按“运行”)

const fn1 = () => {
  const bar = document.querySelector('#bar');
  for (let i = 0; i < 9999999; i++) bar.textContent = 'bar1';
};
const fn2 = () => {
  const bar = document.querySelector('#bar');
  for (let i = 0; i < 9999999; i++) {
    // The following condition will never be fulfilled:
    if (bar.textContent !== 'bar2') bar.textContent = 'bar2';
  }
};

const now0 = performance.now();
fn1();
const now1 = performance.now();
fn2();
const now2 = performance.now();
console.log(now1 - now0);
console.log(now2 - now1);
<div id="bar"></div>

另一方面,在Firefox 56上,查找似乎几乎不需要时间(而赋值 的计算量很大)

但是,如果您有吨和吨元素,那么这只是担心的事情。除非您要处理成千上万的元素,否则就没有必要对其进行优化。

答案 1 :(得分:0)

不必检查属性是否已经具有您要为其分配的值。浏览器将确定该值是否实际更改,并进行相应处理。

答案 2 :(得分:0)

由于在您的示例中,您已经调用了DOM方法getElementById,这是检查属性的最慢的部分,它比对属性进行更改要快得多。因此,最好保持尽可能少的DOM操作

UPD @CertainPerformance的测试表明,不同浏览器的性能有所不同=)