The Business Value of Speed - A How-To Guide - Part 3: Optimizations for the Critical Rendering Path
Last week I already published the second part of this series about performance metrics and mapping them to business values. In this part, I want to show a fast and straightforward to apply solutions to optimize for the Critical Rendering
Path.
If you missed part 1 and part 2, I recommend you to go through the sequence of steps of the Critical Rendering Path in the first part, and relevant performance metrics and mapping them to business values in the second part.
This post is the last post of this series. I hope you enjoy it. If so, stay tuned for the next posts with my newsletter.
- Week 1: Critical Rendering Path
- Week 2: Measure Key Metrics and map them to Business Metrics
- Week 3: Optimizing for your Business value
Tldr;
This post is the third of the series about how to get the business value of site speed. In this part, we dive into the optimization of the Critical Rendering Path. On one side I show you some fast and straightforward solutions to apply, and on the other hand, you read about the long-term solutions.
Table of Contents
1. Introdcution
You already know what the Critical Rendering Path is about and why it is so important. Now I want to show you how you can optimize for the Critical Rendering Path and in the best case with a fast and straightforward solution.
I walk through the main parts that are involved in the CRP like JavaScript, CSS and the HTML. As we now know how the browser processes them, we can take action. By optimizing for the Critical Rendering Path, we simply improve the time to the first render.
Keep in mind that you do not need to load all your assets in the under 1-second aim we set in part 1. Load things later is your best friend!
2. Optimizing for the CRP
Generally speaking from the theory of the Critical Rendering Path, we want to archive the following:
- Minimize the number of bytes we send to the browser
- Reduce the number of critical resources
- Shorten the Critical Rendering Path length
- Defer all non-critical assets
But how do we get there? For some who are regularly reading my blog, what comes now is well known. The most crucial rule in web performance: Measure before you optimize! There are some essential metrics about the initial render of your page that you can receive from webpagetest.org or webpagetest.org or Lighthouse, but as you read
in part two, nothing beats Real User Monitoring.
Itâs not a secret that fewer assets result in faster sites and faster rendering. But many sites still donât use these straightforward techniques to improve.
Remove unsused parts
Unused CSS and JavaScript is possibly the biggest problem. You are blocking the parser and the render without having any benefit. How to remove it? You can use any tool that can tree-shake your unused code away. Depending on your environment, you might search for similar tools like the following, that I use:
Bundler tools
If you want to check how much CSS and JS code in your application is unused, you can view it in the Chrome Dev tools. And for example, if you are using webpack, you can install the Webpack Bundle Analyzer to help analyze your installed packages.
Use Code-Splitting
Code-Splitting is probably the most effective way to remove unused JavaScript. In many cases, it is easy to set up and has a massive improvement for your site. Check the Tooling.Report for bundlers with
Code-Splitting.
Check your imports
Always use the direct import of the code you need, when you implement on your runtime code. The bundlers above can work this out for you with tree-shaking and just import the necessary parts.
import _ from 'lodash';
import { find, groupBy } from 'lodash';
Seperate critical CSS and non-critical CSS
CSS files are render-blocking. The browser must load and process them before it can paint the first pixel. To have a fast render and still lots of awesome styles, you can separate your critical from the non-critical CSS. You critical CSS is everything that you need to display the content above the fold. You can define it by yourself, whatâs critical for you and whatâs not critical.
How does this look work? Letâs make an example consider the following line in your HTML:
<head>
...
<link rel="stylesheet" href="styles.css">
</head>
In this case, the browser loads the styles.css
file from the server and parses it right away while it blocks the rendering process. We can fix this by extracting the critical parts and inline them. For the sake of simplicity imagine we have an img
and a h1
above the fold. Our inline CSS would look like this:
<head>
<style>
.img {
max-width: 100%;
}
h1 {
font-size: 30px
}
</style>
</head>
But what happens with the rest of our styles? We defer them with a little trick. Check out the following two lines and read them carefully:
<head>
<style>
.img {
max-width: 100%;
}
h1 {
font-size: 30px
}
</style>
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
</head>
And did you get it? Simple right? With these to lines, we can load the rest of your CSS asynchronously. Note: The <noscript>
-tag acts as a fallback for some browsers and the this.onload=null
will help some browser not to re-call the stylesheet.
Seperate CSS for different screens
For CSS, you can apply some resource-specific information for the browser. You probably all know the print
attribute for the link
-tag. The browser still downloads the print.css stylesheet, but it wonât block the rendering.
<link rel="stylesheet" href="print.css" media="print" />
You can use the media
attribute to apply the screen specification.
<link rel="stylesheet" href="style.css" media="screen" />
<link rel="stylesheet" href="portrait.css" media="orientation:portrait" />
<link rel="stylesheet" href="widescreen.css" media="(min-width: 42rem)" />
Minification
Minify your assets. This advice is fashionable but still not used widely - Minify your JavaScript, your CSS and your HTML. HTML is render-blocking as well đ! With minification, you remove all unnecessary parts of your code like whitespaces and comments.
For webpack you can use the optimize-css-assets-webpack-plugin
or terser
, for grunt the grunt-contrib-cssmin
and for gulp the gulp-clean-css
plugin. Just to name a few.
Newsletter
Hello and welcome! Don't miss out on crucial web performance insights, plus the latest on accessibility and sustainability, delivered directly to your inbox. Elevate your craft in creating fast, user-friendly, and eco-conscious websites. Sign up now to access seasoned expertise and the freshest news!
Data compression
With compression, you can modify your data with a compression algorithm. Gzip is the most popular, but with Brotli there is a newer and even better compression algorithm you can use. If you want to check if your server supports Brotli, you can use the Brotli.pro tool.
Combine CSS and JS files
With the bundlers mention above, you are also able to combine your stylesheets or JavaScript files to reduce the number of critical resources.
Making JavaScript unblocking
For JavaScript, we have several possibilities depending on your use case and the task of the JavaScript. As JavaScript is render-blocking, you should use one of these options to improve your site.
- Load JavaScript asynchronously
With the attribute async
you tell the browser to load your script asynchronously. As soon as the DOM parser encounters the script tag the browser requests it from the server and continues parsing the DOM. The script, therefore, does not block the HTML parser.
<script src="app.js" async></script>
- Defer JavaScript
The defer
attribute tells the browser to run the script after the HTML parser finishes parsing the document, but before the event, DOMContentLoaded fires. But you can not use this technique for inline scrips.
<script src="app.js" defer></script>
- Re-order inline scripts
For inline script, unfortunately, you can not use async or defer. Inline scripts execute right away the browser parses them. Therefore you can place them at the end of your HTML right before the closing body tag.
3. Next steps
You find all the resources for this article on GitHub. Feel free to check it out, try some stuff or fork it.
After this series on the Business Value of Speed, you should be well packed to understand all the essential browser functions and processes, how to measure and map performance and business metrics and how to optimize your site for the Critical Rendering Path.
3. Conclution
Where are we now? In the last parts of my series, you read much about the Critical Rendering Path and what the browser needs to do before it can display your site. In the second part, I wrote about the relevant metrics and how you can map them to business values in Plausible Analytics. In this part of the series, you learned about simple optimizations for the Critical Rendering Path and your key metrics.
If you like this article, smile for a moment, share it, follow me, check out my RSS feed and subscribe to my newsletter.
Cheers Marc
Further Reading
- Minify JavaScript
- Minify CSS
- Critical Rendering Path
- Optimizing Website Performance and Critical Rendering Path