Reputation: 726
This question stems from a conundrum I am facing in Javascript, though a more general scientific response would be extremely helpful.
If an object or array is being iterated over for another purpose—and it is known that only one element of interest has changed which can be acted upon for manipulation—is it best to:
Simply replace every element with new data to reflect the change
Rigorously check each element and replace only that which has changed
(In this example, heights of all bars of a graph are being adjusted—as they are relative—though only one textual piece of information is targeted for change.)
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'];
});
Or:
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'];
});
I suppose this is a question that exposes my ignorance and it has made it difficult for me to research a conclusion: Is it more computationally exhausting to replace all elements when a difference is known to exist somewhere in the set, or is it cheaper to seek out the offending individual and change only that value?
(Setting timers, i.e. console.timeEnd(), has proved inconclusive.)
Any education would be throughly appreciated. I can't get my head around it.
Upvotes: 1
Views: 134
Reputation: 2356
Since in your example you have already called DOM method getElementById
which is the slowest part checking the property is way faster than performing a change to it. So it's always better to keep DOM-manipulations as little as possible.
UPD @CertainPerformance's test shows that performance varies amongst browsers =)
Upvotes: 0
Reputation: 371233
It depends on the browser.
On Chrome and Opera, at least, plain assignment without checking looks to be more performant than looking up the existing text, even without possible assignment on top of looking up the existing text, by an order of around 3x:
(warning: running the following code will block your browser for some time, only press "Run" if you're sure)
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>
On the other hand, on Firefox 56, the lookup seems to take next to no time at all (whereas assignment is computationally expensive)
But this is only really something to worry about if you have tons and tons of elements. Unless you're dealing with thousands or tens of thousands of elements, it's not something worth optimizing for.
Upvotes: 2
Reputation: 51944
It's not necessary to check if the property already has the value you're assigning to it. The browser will determine if the value actually changed and handle it accordingly.
Upvotes: 0