One of the most representative aspects in the load time of a web page are its CSS files. The reason is simple, browsers stop the rendering of the page until each of the CSS files within the head tag have been loaded, parsed and executed. This means that if you load a CSS file that is too large within the head tag, the page will take as long as that file takes to download to show itself. This can result in a time where the web page is blank and it can be enough for a user to click on the Back button and go to another web page.
The above is known as Render-blocking CSS, or CSS that blocks the presentation. While it is true that some styles are strictly necessary and their absence would result in loss of page functionality, others are not as essential and can be loaded only when necessary. Next, we will see some cases in which we can optimize the load times of these CSS files based on this premise.
CSS Type and Media Queries
The type and media queries are essential to know when a CSS is loaded. Let's see some examples.
<link href="style.css" rel="stylesheet"> <link href="style.css" rel="stylesheet" media="all"> <link href="print.css" rel="stylesheet" media="print"> <link href="other.css" rel="stylesheet" media="(min-width: 40em)"> <link href="portr.css" rel="stylesheet" media="orientation:portrait">
1. The first declaration blocks the presentation because if the media attribute is not specified, the browser assumes by default the value all, that is, all media. In any case, the CSS will be loaded.
2. The second declaration explicitly defines all media, so it is exactly the same as the previous example and always blocks the presentation.
3. The third declaration does not block the presentation because it only applies to printing the page. It would be necessary for the user to try to print the page for that event to trigger the loading of the CSS.
4. The fourth declaration will block the presentation when the specified condition is met.
5. The last declaration could block the presentation depending on the orientation of the device at the time of loading the page. If the page is loaded in portrait, it will block the presentation.
It was already said that by default browsers treat CSS files as resources that block the presentation. However, there is a way to asynchronously load these resources. Let's see an example loading external fonts on a web page.
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">
The above code shows a very common way to load a Google font. The problem with this is that it leaves the FCP (first contentful paint) after loading the fonts. The FCP is the first screen that is shown to the user. In the following image you can see that the FCP is around 240 ms when loading three Google fonts. Before that, the page is blank as you can see in the thumbnail previews.
The way to load this resource asynchronously is as follows:
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'">
As you can see, the change made is in the
rel="preload" attribute. In addition to this, it is necessary to indicate to the browser what type of resource is going to be loaded, in this case
onload attribute ensures that the CSS is processed when it finishes loading and the
null value in the assignment prevents it from being loaded twice in some browsers. We can see the change in performance once the change is made below.
<noscript> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet"> </noscript>
A look at the Google Lighthouse reports can give us a more complete picture of the resources that block the presentation on a web page.
While this may seem sufficient, I invite you to review our article What is Critical CSS and how can it optimize FCP? to further delve into the performance of resources that block the presentation. See you there!.