Look at this example:
const startTime = performance.now();
setTimeout(() => console.log(`taken time: ${performance.now() - startTime}ms`))
for(let i = 0; i < 1000; i++){
const element = document.createElement("div");
document.body.appendChild(element);
element.textContent = `Текст n${i}`;
window.getComputedStyle(document.body);
}
and look at another one:
const startTime = performance.now();
setTimeout(() => console.log(`taken time: ${performance.now() - startTime}ms`))
for(let i = 0; i < 1000; i++){
const element = document.createElement("div");
document.body.appendChild(element);
element.textContent = `Текст n${i}`;
window.getComputedStyle(document.body).width;
}
Differences are minimal: in the first case I just invoke window.getComputedStyle(document.body) without getting property, and in the second case I doing it with width property. As a result in first one we don't see recalculation styles and reflows but in the second one we see vesa versa situation. Why?
This is because
getComputedStyle(element)actually returns a live object.Getting this object doesn't require that a full recalc is performed, only its
getterswill force it.But browsers are nowadays even smarter than just that, they won't even trigger a reflow for some properties outside of the CSSOM tree that affects the CSSStyleDeclaration object being inspected.
For instance in the following example we can see that getting the
fontSizeproperty from the CSSStyleDeclaration of an element that is inside our checker will force a reflow affecting our checker, while getting one form outside won't, because unlikewidth, thefontSizeproperty is only affected by ancestors and not by siblings.The same checking for
widthwould trigger in both cases, becausewidthcan be affected by siblings: