The Business Value of Speed - A How-To Guide - Part 3: Optimizations for the
  Critical Rendering Path
Tags: webperf, css, webdev, javascript
Published: 2020-07-30 14:43:54

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](https://marcradziwill.com/newsletter/) for the next posts with my newsletter.

- Week 1: [Critical Rendering Path](/business-value-of-speed-part-one-critical-rendering-path)
- Week 2: [Measure Key Metrics and map them to Business Metrics](/business-value-of-speed-part-two-metrics-and-mapping-of-business-values)
- Week 3: [Optimizing for your Business value](https://marcradziwill.com/blog/business-value-of-speed-part-three-optimizations/)

---

If you like this article, smile for a moment, please share it, follow me and [subscribe to my newsletter](https://marcradziwill.com/newsletter/).

---

## 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. [Introduction](#into)
2. [Optimizing for the CRP](#opti)
   - [Remove unused parts?](#unsused)
   - [Bundler tools](#tools)
   - [User Code-Splitting](#codesplitting)
   - [Check your imports](#imports)
   - [Seperate critical CSS and non-critical CSS](#noncritical)
   - [Seperate CSS for different screens](#screens)
   - [Minification](#minification)
   - [Data compression](#compression)
   - [Combine CSS and JS files](#combine)
   - [Making JavaScript unblocking](#unblocking)
3. [Next steps](#next)
4. [Conclution](#conclution)

## 1. Introdcution <div id="intro"></div>

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 <div id="opti"></div>

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](https://www.webpagetest.org/) or Lighthouse, but as you read in part two, nothing beats [Real User Monitoring](https://en.wikipedia.org/wiki/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 <div id="unsused"></div>

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 <div id="tools"></div>

- [webpack](https://webpack.js.org/)
- [Rollup](https://rollupjs.org/guide/en)
- [Parcel](https://parceljs.org/)
- [Tooling.Report (Feature detecting tool for bundlers)](https://bundlers.tooling.report/)

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](https://github.com/webpack-contrib/webpack-bundle-analyzer)
to help analyze your installed packages.

### Use Code-Splitting <div id="codesplitting"></div>

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](https://bundlers.tooling.report/code-splitting/).

### Check your imports <div id="imports"></div>

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.

```js
import _ from 'lodash'
import {find, groupBy} from 'lodash'
```

### Seperate critical CSS and non-critical CSS <div id="noncritical"></div>

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:

```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:

```html
<head>
  <style type="text/css">
    .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:

```html
<head>
  <style type="text/css">
    .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 <div id="screens"></div>

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.

```html
<link rel="stylesheet" href="print.css" media="print" />
```

You can use the `media` attribute to apply the screen specification.

```html
<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 <div id="minification"></div>

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.

### Data compression <div id="compression"></div>

With compression, you can modify your data with a compression algorithm. [Gzip](https://www.youtube.com/watch?v=whGwm0Lky2s&feature=youtu.be&t=14m11s) is the most popular, but with [Brotli](https://opensource.googleblog.com/2015/09/introducing-brotli-new-compression.html) 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](https://www.brotli.pro/) tool.

### Combine CSS and JS files <div id="combine"></div>

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 <div id="unblocking"></div>

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.

1. 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.

```html
<script src="app.js" async></script>
```

2. 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.

```html
<script src="app.js" defer></script>
```

3. 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 <div id="next"></div>

You find all the resources for this article on [GitHub](https://github.com/marcradziwill/critical-rendering-path-tutorial). 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 <div id="conclution"></div>

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 Google 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](https://marcradziwill.com/blog/rss.xml) and [subscribe to my newsletter](https://marcradziwill.com/newsletter/).

Cheers Marc

### Further Reading

- [Minify JavaScript](https://web.dev/unminified-javascript/)
- [Minify CSS](https://web.dev/minify-css/)
- [Critical Rendering Path](https://developers.google.com/web/fundamentals/performance/critical-rendering-path)
- [Optimizing Website Performance and Critical Rendering Path](https://www.toptal.com/web/website-performance-critical-rendering-path)