Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If CSS is render-blocking, why do we see FOUC?

In order to construct the render-tree, the browser requires both DOM and CSSOM. CSSOM can only be constructed, once the CSS is downloaded. In essence, once the CSS is downloaded the page should be rendered alright. But, why do we see Flash Of Unstyled Content(FOUC) on the page? In what time window does the browser show unstyled content?

Please help me understand this.

Ref: https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-blocking-css

like image 994
Vishnu Sankaran Avatar asked Nov 09 '18 05:11

Vishnu Sankaran


People also ask

What causes FOUC?

A FOUC occurs when the browser loads the content or, technically speaking, the HTML of the site before it delivers the styles (CSS) – this causes you to see the raw, un-styled pieces of information whilst the server is still delivering the styling files, thus causes the site to “FLASH” and after that; VOILA the site ...

Does CSS block the render?

By default, CSS is treated as a render blocking resource, which means that the browser won't render any processed content until the CSSOM is constructed. Make sure to keep your CSS lean, deliver it as quickly as possible, and use media types and queries to unblock rendering.

How do you avoid a flash of unstyled content FOUC while still keeping your site accessible to all users?

In an attempt to avoid unstyled content, front-end developers may choose to hide all content until it is fully loaded, at which point a load event handler is triggered and the content appears, though an interruption of loading might leave behind a blank page, to which unstyled content would be preferable.


2 Answers

I still don’t agree with the accepted answer, because according to the critical rendering path nothing could be painted on a screen under normal circumstances until the render tree (DOM + CSSOM) is build.

I find that this Google article is somewhat confusing at the first glance but it becomes less contradictory if we take a look carefully at the following statement:

“What would happen if we try to render a typical page without blocking rendering on CSS?”. (Then NY Times FOUC as example of behaviour without blocking rendering follows.)

The thing is historically FOUC happened for different reasons in different browsers versions and on different circumstances.

For example according to this ancient article we could encounter FOUC in web kit if some JS attempted to access properties that have layout/style information.

Web Kit has the opposite behavior and will continue parsing a page even after a style sheet directive has been encountered so that style sheet and script loads can be parallelized. That way everything can be ready for display much earlier.

The problem with this behavior is what to do when a script attempts to access a property that involves having accurate layout/style information to answer. Shipping Safari’s current behavior when this happens is as follows: it will go ahead and lay out what it’s got even though it doesn’t have the style sheet yet. It will also display it. This means you see FOUC whenever a script tries to access properties like scrollHeight or offsetWidth before the style sheet has loaded.

Therefore when we say “FOUC happens” there should be explications on what circumstances and in what browser it happens, because it doesn’t “just” happens everywhere.

like image 58
Staneque Avatar answered Oct 21 '22 06:10

Staneque


The basic reason for FOUC is -> new/different styles are getting applied after elements were already painted on screen.

Now comes the question -> can FOUC happens when page is loading and page markup itself includes <link> tag for external css, at high level it appears this should not happen as css is render blocking and there should be no case where any element can get rendered without its computed styles, but it(FOUC) happens on page load in certain conditions.

Main reason for that is dom tree construction is incremental i.e. without having the full html markup browser can render partial html whatever is downloaded till the given point of time.

To understand that lets take example of following html -

<!DOCTYPE html>
<html lang="en">
  <body>
    <100 html tags block 1 />
    <link href="css1" />
    <100 html tags block 2 />
    <link href="css2" />
    <100 html tags block 3 />
    <link href="css3" />
  </body>
</html>
  1. First 100 tags are converted to dom and with help of existing cssom(which was construed from user agent stylesheets) forms render tree, which will be painted and will be visible to user.
  2. After that parsing will be blocked till css1 is downloaded and new cssom is created with useragent+css1 styles.
  3. And with new render tree(formed via old dom + new cssom) html block 1 will be updated(FOUC)
  4. Then html block 2 is similarly processed as it gets downloaded after that.
  5. Now same things as step 3 is repeated with block 2 and block 3
  6. And same goes on till the end of document

Credits - https://medium.com/jspoint/how-the-browser-renders-a-web-page-dom-cssom-and-rendering-df10531c9969

like image 36
Rohit Garg Avatar answered Oct 21 '22 07:10

Rohit Garg