3

In my question, DOM redraw methods are those that modifies the DOM and cause browser to redraw the page. For example:

const newChildNode = /*...*/;

document.body.appendChild(newChildNode);

const newHeight = document.body.scrollHeight;

This code works fine under normal circumstances, but I am not so sure how it behaves under high pressure conditions, like when there are so many request to redraw the page. Can I assume that when document.body.scrollHeight is executed, newChildNode is already visible on screen?

kkkkkkk
  • 7,628
  • 2
  • 18
  • 31

1 Answers1

16

We can divide this "redraw" process in 3 parts, DOM update, Reflow, Repaint.

All these operations do not follow the same rules:

DOM update: Always synchronous. The DOM is just an other js object, and its manipulations methods are all synchronous.

Reflow: That's the strange beast you stumbled upon. This is the recalculation of all box positions of the elements on the page.
Generally, browsers will wait until you finished all DOM modifications, and thus, the end of the js stream, before triggering it.
But some DOM methods will force this operation, synchronously. e.g, all the HTMLElement.offsetXXX and alike properties, or Element.getBoundingClientRect, or accessing in-doc's Node.innerText or accessing some properties of getComputedStyle returned object (, and probably others) will trigger a synchronous reflow, in order to have the updated values. So beware when you use these methods/properties.

Repaint: When things are actually passed to the rendering engines. Nothing in the specs says when this should happen. Most browsers will wait the next screen refresh, but it's not said it will always behave like that. e.g. Chrome is known for not triggering it when you blocked the scripts execution with alert(), while Firefox will.

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • 1
    "Chrome is known for not triggering it..Fireox" how the hell people find this stuff out ? who knows this stuff or how does one come by this knowledge? What sources do you subscribe to? Just asking so that I too can subscribe to them. – jimjim May 17 '19 at 01:28
  • 2
    @Arjang Answering StackOverflow questions helps a lot in finding all kind off oddities, browser quirks, and bugs both in the implementations or specs themselves ;-) For instance I took notice of that one with https://stackoverflow.com/questions/41346772/how-do-i-know-when-html5-canvas-rendering-is-finished/41347460#41347460, but then I dig this up with https://stackoverflow.com/questions/52325435/why-blocking-event-loop-does-not-block-css-animation/52326008 and in between there had been https://stackoverflow.com/questions/43728379/forcing-a-repaint-rerender-in-chrome-after-style-changes – Kaiido May 17 '19 at 01:39
  • Good answer, but could you rephrase "*the end of the js stream*" a bit? Just "end of the (current) js execution" maybe - or did you mean an empty event queue? – Bergi Sep 02 '22 at 03:01
  • @Bergi actually different browsers will behave quite differently here. Not sure how to keep it simple. WebKit will apparently wait for some idle status before triggering the reflow. Blink and Gecko will wait until the next repaint. But all will at least wait until the current script execution is done, and even more: they'll all wait for after MutationObserver's notifications are dispatched, but it may be before the next event loop iteration, for instance if you're in a rAF callback... So the vague "JS stream" was quite compelling for this :-P But if you can find a better wording I'll take it. – Kaiido Sep 02 '22 at 03:10