这个问题源于我在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())没有定论。)
任何教育都会受到赞赏。我无法解决这个问题。
答案 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的测试表明,不同浏览器的性能有所不同=)