Client was experiencing a FOUC with a third party that looked a little like this. Seems like a JS kinda problem, right? Kind of… https://t.co/0xi5s7EvVe (View Tweet)
Their markup looked like this. The HTML and its styles were right there in the HTML, with a link out to the third party script between the two. The FOUC lasted as long as the script took to fetch and execute. Again, a JS problem, right?
(View Tweet)
Wrong! Remember, HTML is synchronous and parsed line by line. The problem isn’t with the JS—it’s that the browser can’t even SEE that there’s a style tag until the JS is fully dealt with. (View Tweet)
The browser can parse and render the plugin’s HTML right away but then is halted while it solves the end-to-end JS, at which point it discovers the style and then has to restyle the already-rendered HTML. The fix? (View Tweet)
Nudge the style information BEFORE the HTML that needs it [note: always do this]. Now we have both the markup and its CSS available before the browser needs to pause.
(View Tweet)
This is, of course, a grossly oversimplified demo of a much more specific problem my client was having, but the point still stands: HTML is parsed line-by-line, and while the parser is ‘stuck’ on line x, it can’t even see line x+n. (View Tweet)
Interestingly, I recently (as)used this behaviour to demonstrate the impact of a late-loading modal on LCP, without actually having to build a late-loading modal:
(View Tweet)