How-to

10 Web Performance quick wins you can and should apply in under 5 minutes

Optimizing the performance of your website takes time, and If you want to work on it towards your individual needs, it can be much work.

I haven’t seen any case in my career where it wasn’t worth it, but you still need to have the time and money to do these optimizations. Fortunately, Web Performance has some quick-wins. Quick-wins are little changes you can apply in under 5 minutes to your website.

Tldr;

In this post, I show you 10 Web Performance quick-wins you can (and should) apply to your site in under 5 minutes. These quick-wins can be little changes to your code-base or your server configuration.

Why should you apply them

First, it takes maximum 50 minutes to apply these changes, but furthermore, even if you do not get a huge performance boost in your measurements, I would consider these quick-wins as Web Performance best practices. They are simple and easy to implement, don’t require a detailed understanding of the part they are applied to and can have a significant impact on your performance.

Web Performance quick-wins

1. Use text compression

With text compression, you minimize the number of bytes that are transferred over the network. There are several compression algorithms. 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.

If your server does not support Brotli, you can install it with the following straightforward guides:

Probably this is the first quick-win you get for free because most of the hosting platforms or CDN provider either compress assets by default or allow you to configure them.

2. Image compression

Uncompressed images are a huge potential performance bottleneck. If you do not compress your images before serving them to the user, you transfer unnecessary bytes through the wire. There are several useful tools you can use to compress your images in a fast way without losing visible quality. For my pictures, I use Imagemin. It supports many image formats, and you can use it as a comand line interface or as an npm module.

imagemin img/* --out-dir=dist/images

You can implement the npm module into your bundler like webpack, gulp or grunt. With imagemin-mozjpeg you compress your JPEG images to a quality of 60%: The range goes from 0 being the worst and 100 the best.

const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');

(async() => {
  const files = await imagemin(
      ['img/*.jpg'],
      {
        destination: 'dist/img',
        plugins: [
          imageminMozjpeg({quality: 60}),
        ]
      }
  );
  console.log(files);
})();

In my case, it reduces the file size from 4MB to 100kB. Check out the working demo code in my Github repository.

unitfile size without compressionfile size with compressionfilesize decrease in %
Bytes4156855 Bytes103273 Bytes-97%
MB/kB4MB103 kB-97%

3. Image format

Use modern image formats can give you a real boost for your performance. WebP images are smaller than JPEG and PNG, usually by about 25% - 35%. WebP has a wide support by browsers. Even though all browsers do not support it, it is worth implementing this quick-win.

We use the imagemin npm package an add the WebP plugin for it. The following code outputs the WebP version of my image into the dist folder.

const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp');

(async() => {
  const files = await imagemin(
      ['img/*.jpg'],
      {
        destination: 'dist/img',
        plugins: [
          imageminWebp({quality: 50})
        ]
      }
  );
  console.log(files);
})();

Let’s have a look at the filesizes again:

unitfile size without compressionfile size with compressionfilesize decrease in %
Bytes4156855 Bytes58940 Bytes-98%
MB/kB4MB59 kB-98%

The results speak for themselves the file size decrease compared to the original image is 98%, and compared to the compressed JPG file, it is even more visible how good WebP compress your images. The WebP version is 43% smaller than the compressed JPEG version.

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!

4. Image lazy-loading

Lazy-loading images is a technique to load offscreen images later and not in advance. Images that are loaded right when the parser encounters them slow down the initial page load. With lazy-loading, you can speed up this process and load images later. You can do this easily with lazysizes. With the lazysizes script and the native browser support for the loading attribute, you can change your images from:

<img src="image.jpg" alt="">

to:

<img data-src="image.jpg" class="lazyload" alt="">

The library takes care of the rest, and you can verify this with your browser. Open your site and locate your image tag. If the class changed from lazyload to lazyloaded it works. Furthermore, you can check the Lighthouse audit for “Defer offscreen images”.

5. Cache your assets / HTTP Cache headers

Caching is one method of how you can quickly improve your sites speed. It reduces the page load time for returning visitors. You can tell the browser cache files for a specific time. If you have access to your server caching is simple and straightforward to apply.

You can use the following API for caching:

6. Inline your critical CSS - defer uncritical CSS

CSS is render-blocking. That means the browser must download and process all CSS files before it can paint a pixel. By inlining your critical CSS, you can speed up this process dramatically. You do this by defining your critical CSS. The critical CSS are all styles above-the-fold, so all content in the user’s viewport.

You do this with the following steps:

Identify your critical CSS

If you do not know what your critical CSS is you can use Critcal, CriticalCSS or Penthouse. All these libraries extract the CSS from your HTML files that are visible in the given viewport.

See the working example of criticalCSS.

var criticalcss = require("criticalcss");

var request = require('request');
var path = require( 'path' );
var criticalcss = require("criticalcss");
var fs = require('fs');
var tmpDir = require('os').tmpdir();

var cssUrl = 'https://web.dev/app.css';
var cssPath = path.join( tmpDir, 'app.css' );
request(cssUrl).pipe(fs.createWriteStream(cssPath)).on('close', function() {
  criticalcss.getRules(cssPath, function(err, output) {
    if (err) {
      throw new Error(err);
    } else {
      criticalcss.findCritical("https://web.dev/", { rules: JSON.parse(output) }, function(err, output) {
        if (err) {
          throw new Error(err);
        } else {
          console.log(output);
          // save this to a file for step 2
        }
      });
    }
  });
});

Inline Critical CSS

The HTML parser encounters the style-tag and processes the critical CSS right away.

<head>
  <style>
  body {...}
  /* ... rest of the critical CSS */
  </style>
</head>

Defer uncritical CSS

The uncritical CSS doesn’t need to be processed right away. The browser can load it after the onload event so that the user doesn’t have to wait.

<link rel="preload" href="/assets/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/assets/styles.css"></noscript>

7. JavaScript Asynchronious / Defer loading / lazy-load

JavaScript is HTML parser blocking. The browser has to wait for JavaScript to execute before it can finish parsing the HTML. But you can tell the browser to wait for the JavaScript execution.

Load JavaScript asynchronously

With the attribute async you tell the browser to load your script asynchronously.

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

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

Re-order inline scripts

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.

8. Use resource hints to speed up delivery.

Resource Hints help developers to tell the browser what the page later might load. The specification defines four primitives:

  • preconnect
  • dns-prefetch
  • prefetch
  • prerender

Additionally, to resource hints, we make use of the preload keyword for the link-attribute.

How can you use them:

preconnect

The following line in your head tells the browser that you want to establish a connection to another domain. The browser will prepare for this connection. Using the preconnect link tag can speed up your load time by 100–500 ms. When do you should use it? Directly speaking: When you know where you what to fetch something but don’t know what. Like a hashed style file (styles.2f2k1kd.css).

<link rel="preconnect" href="https://example.com">

dns-prefetch

You should use preconnect for your most critical connections if you want to tell the browser that you will establish a connection to a non-critical domain you can dns-prefetch them. In average, this will save you between 20–120 ms.

<link rel="dns-prefetch" href="http://example.com">

prefetch

With prefetch, you tell the browser to download the entire site that you are referring to in the link tag. You can prefetch pages or assets. Prefetching is a helpful technique to speed up your website, but you should take care of situations where it can decrease your site speed.

Low-end devices or users on a slow network might have problems because the browser is busily prefetching. You could consider combining prefetching with adaptive loading or use smart prefetching with quicklink and Guess.js

<link rel="prefetch" href="index.html" as="document">
<link rel="prefetch" href="main.js" as="script">
<link rel="prefetch" href="main.css" as="style">
<link rel="prefetch" href="font.woff" as="font">
<link rel="prefetch" href="image.webp" as="image">

prerender

<link rel="prerender" href="https://example.com/content/to/prerender">

With prerendering, the content is loaded and then rendered in the background. When the user navigates to the prerendered content, it is displayed instantly.

preload

With preload, the browser gets the hint that the referring asset is important, and it should fetch it sooner. Modern browsers are already pretty good at prioritizing resources so that you should use preload only for critical resources. Consider using preconnect and prefetch instead or try out instant.page.

<link rel="preload" as="script" href="critical.js">

9. Fasten your Google Fonts

Google Fonts are fantastic. They offer excellent service and are widely used. If you don’t want to host your fonts by yourself, Google Fonts is a proper choice. But you should take care of how you implement them. Harry Roberts wrote an excellent in-depth article about The Fastest Google Fonts. I strongly recommend you to read it.

If you just want your quick-win use the snippet below for your Google Font integration but the credit goes to Harry.

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=...&display=swap"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=...&display=swap" media="print" onload="this.media='all'"/>
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=...&display=swap"/></noscript>

10. Use a service worker to cache your assets

A service worker is a script that your browser runs in the background. Caching is probably the most used feature and the feature you should use. I think this is not a matter of option. By implementing caching with a service worker, you can make the user interaction with your site faster and make it accessible even if the user is not online.

I wrote a blog post about how you can implement a service worker. As this article is a 10-minute read, you can also use the code in the associated repo.

Remove 404 links

404 pages and responses can slow down your website. Try to find them and fix or remove the requests. You can use the Google Search Console or the app SEO-Spider.

Serve legacy code only to legacy browsers with module/nomodule pattern

Make use of the module/nomodule pattern. The module pattern let you service legacy code to legacy browsers and modern code to modern browsers without serving the modern one with all the polyfills.

<!-- lagacy code with polyfill for old browsers -->
<script nomodule src="/polyfills/full.min.js"></script>
<!-- module bundle for browsers with ES2015+ support -->
<script type="module" src="/polyfills/modern.min.js"></script>

::::

Conclusion

In this post, I presented you 10 Web Performance quick-wins you can apply in under 5 minutes to your website to improve your sites speed. You find the resources in the following GitHub repo.

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




Likes 3
Like from edgemesh
Like from Wen
Like from Benjamin Angel
Reposts 3
Like from Srikanth Dyapi
Like from Wen
Like from MachMetrics