As you probably know, JS execution blocks parsing and rendering of the DOM tree, but does CSS loading block parsing and rendering of the DOM tree? Next, let’s analyze it together.

The principle of analytic

So why does the above phenomenon occur? Let’s take a look at the browser’s rendering process. Different browsers use different kernels, so their rendering process is different. There are mainly two

  • Webkit rendering process

  • Gecko rendering process

As can be seen from the above two flow charts, the browser rendering process is as follows:

  • HTML files are parsed to generate A DOM Tree, and CSS files are parsed to generate a CSSOM Tree
  • Combine Dom Tree with CSSOM Tree to generate Render Tree
  • Render pixels onto the screen according to Render Tree.

We can see that in the process

  • DOM parsing and CSS parsing are parallel processes, so this explains why CSS loading does not block DOM parsing.
  • However, since the Render Tree is dependent on the DOM Tree and the CSSOM Tree, he must wait until the CSSOM Tree is built, i.e. the CSS resource is loaded (or the CSS resource fails to load), before he can start rendering. Therefore, CSS loading blocks Dom rendering.
  • Because JS may manipulate previous Dom nodes and CSS styles, browsers maintain the order of CSS and JS in HTML. Therefore, the stylesheet will be loaded and executed before any subsequent JS is executed. So CSS blocks subsequent JS execution.

DOMContentLoaded

For browsers, there are two main events for page loading, one is DOMContentLoaded and the other is onLoad. OnLoad does not trigger until all resources on the page have been loaded, such as CSS, JS, images and videos.

DOMContentLoaded, as the name implies, triggers this event when the content of the page has been parsed. So, as we discussed above, CSS blocks Dom rendering and JS execution, and JS blocks Dom parsing. So we can make this assumption

  • DomContentLoaded does not need to wait for the CSS to finish loading when only CSS exists on the page, or when js is in front of the CSS.
  • DomContentLoaded does not trigger until both CSS and JS are loaded on a page and the JS is behind the CSS.

Let’s test the first case:

<! DOCTYPE HTML > < HTML lang="en"> <head> <title> CSS block </title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script> document.addEventListener('DOMContentLoaded', function() { console.log('DOMContentLoaded'); })! [](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d30219afd9e84bc99875991b7d284435~tplv-k3u1fbpfcp-zoom-1.image) ! [](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/87519598e6484ec38db8daed23f586c9~tplv-k3u1fbpfcp-zoom-1.image) < / script > < link href = "https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel = "stylesheet" > < / head > <body> </body> </html>Copy the code

As you can see from the animation, the DOMContentLoaded event was triggered before the CSS was loaded. Because CSS doesn’t have any JS code behind it.

Let’s test the second case. It’s as simple as adding a line of code after the CSS

<! DOCTYPE HTML > < HTML lang="en"> <head> <title> CSS block </title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script> document.addEventListener('DOMContentLoaded', function() { console.log('DOMContentLoaded'); }) < / script > < link href = "https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel = "stylesheet" > < script > Console. log(' Is it my turn? '); </script> </head> <body> </body> </html>Copy the code

As you can see, the DOMContentLoaded event is triggered only after the CSS is loaded. Therefore, we can draw the conclusion that:

  • If both CSS and JS exist on the page, and js exists behind the CSS, the DOMContentLoaded event is executed after the CSS is loaded.
  • In other cases, DOMContentLoaded does not wait for CSS to load, and the DOMContentLoaded event does not wait for images, videos, and other resources to load.

conclusion

From what has been discussed above, we can draw the following conclusions:

  • CSS loading does not block parsing of the DOM tree
  • CSS loading blocks DOM tree rendering
  • CSS loading blocks the execution of subsequent JS statements

Therefore, in order to avoid a long white screen time for users, we should make the CSS load as fast as possible. For example, we can use the following methods:

  • Use CDN(because CDN will select the nearest node with cached content to provide resources for you according to your network condition, so it can reduce the load time)
  • Compress CSS (using various packaging tools such as Webpack,gulp, etc., or by enabling gzip compression)
  • Use caches wisely (cache-Control, Expires, and e-tag are all fine, but one thing to be aware of is that you want to avoid caching after updates. One solution is to add a version number after the file name.
  • Reduce the number of HTTP requests, merge multiple CSS files, or simply write inline styles (one of the disadvantages of inline styles is that they can’t be cached)

Welcome to my React Tech Stack chat group