Javascript 最佳实践:更换每个元件或仅检查和更换已更改的元件是否更有效?

Javascript 最佳实践:更换每个元件或仅检查和更换已更改的元件是否更有效?,javascript,Javascript,这个问题源于我在Javascript中面临的一个难题,尽管一个更一般的科学回答将非常有用 如果一个对象或数组被迭代用于另一个目的,并且已知只有一个感兴趣的元素发生了更改,可以对其进行操作,那么最好: 只需用新数据替换每个元素即可反映更改 严格检查每个元件,仅更换已更换的元件 (在本例中,图形中所有条的高度都会进行调整,因为它们是相对的,尽管只有一条文本信息需要更改。) 或: 我想这是一个暴露了我无知的问题,这让我很难研究出一个结论:当已知在集合中某个地方存在差异时,替换所有元素在计算上是否会

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

如果一个对象或数组被迭代用于另一个目的,并且已知只有一个感兴趣的元素发生了更改,可以对其进行操作,那么最好:

  • 只需用新数据替换每个元素即可反映更改

  • 严格检查每个元件,仅更换已更换的元件

(在本例中,图形中所有条的高度都会进行调整,因为它们是相对的,尽管只有一条文本信息需要更改。)

或:

我想这是一个暴露了我无知的问题,这让我很难研究出一个结论:当已知在集合中某个地方存在差异时,替换所有元素在计算上是否会更费劲,还是找出有问题的个体并只更改该值更便宜

(设置计时器,即console.timeEnd(),已证明是不确定的。)


任何教育都将受到充分的赞赏。我无法理解它。

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

这取决于浏览器

至少在Chrome和Opera上,不检查的普通赋值看起来比查找现有文本更有效,甚至在查找现有文本的基础上不可能赋值,大约是3倍:

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

const fn1=()=>{
const bar=document.querySelector(“#bar”);
对于(设i=0;i<999999;i++)bar.textContent='bar1';
};
常数fn2=()=>{
const bar=document.querySelector(“#bar”);
for(设i=0;i<9999999;i++){
//以下条件永远不会满足:
如果(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)

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


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

这正是我希望找到的实验类型。非常感谢。尽管我仍然对科学思想感到好奇:在一个更重要的应用程序中,用一种更负责任的语言进行最佳实践是什么?在safari中,fn2的速度要快5倍(4636 vs 882)@e最好将当前文本内容放在一个变量中(在实际文本内容发生变化时设置),这样,您就不必事先检查DOM本身。您真的可以只考虑这一个,函数完全相同,只是有一个条件检查,这意味着代码越多,时间越长。@chbchb55这不是真的。更多的代码不一定意味着更多的时间,DOM查找与DOM分配是分开的。@当然,您是对的,更多的代码不一定意味着更多的时间,但是,在这种情况下,除了一条
if
语句外,其余的代码完全相同,因此从逻辑上讲,它需要更多的时间。@chbchb55否,因为查找从根本上不同于赋值。如果查找几乎是即时的,并且分配占用了一些CPU周期,该怎么办?若分配几乎是即时的,并且查找占用了一些CPU周期,那个该怎么办?答案会有所不同。请参阅下面我的答案-不同浏览器的答案确实有所不同。对于一些人来说,查找成本更高,而对于其他人来说,分配成本更高。有时,
if
检查可能比没有
if
检查的情况更快。@某些性能可能会略有不同,但如果它运行检查,然后运行代码,则需要比仅运行代码更多的时间。
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'];
});