Improving Performance of Nuxt with Fontaine
Tags: performance, javascript, webdev, tutorial
Published: 2022-11-28 07:57:37

I am always amazed by what you can do to improve the performance of your website by focusing on the things that initially does not look that complex. In the past, I thought that you can only make your app faster by optimizing backend like database operations, requests, etc. Don't get me wrong, you should still work on your backend code to make the requests faster, but there are several things in the frontend that you can do to make the experience much better.

Some time ago, I wrote an article about Improving Performance of Nuxt with PartyTown that allows you to run third party scripts like Google Analytics as a web worker. You can check it out in the following series.

Today however, I will focus on the fonts and in more details, font face override concept.

## What is Fontaine?

[Fontaine](https://github.com/nuxt-modules/fontaine) is a font metric override tool that can:

* Reduce CLS by using local font fallbacks with crafted font metrics.
* Generate font metrics and overrides automatically.
* Pure CSS, zero runtime overhead.

It basically means, that whenever you are using font-face in your project, adding this module to your project will increase the Content Layout Shift (CLS) value of your Lighthouse score, and that will in general improve the performance of your website.

Below, you can see the result of adding the module to the example app using `font-face`:

|             | Before | After   |
| ----------- | ------ | ------- |
| CLS         | `0.34` | `0.013` |
| Performance | `88`   | `98`    |

To achieve even better performance, you should inline all your CSS, not just the font-face override rules (which this module does automatically), or there will still be a layout shift when the stylesheet loads (which is why the number above is not zero). This will be adressed in one of the upcoming releases of Nuxt.

## Usage

Usage of this module is really simple and usually does not require any configuration what so ever. First, let's install the module:

```bash
pnpm add -D @nuxtjs/fontaine

npm install -D @nuxtjs/fontaine

yarn add -D @nuxtjs/fontaine
```

Then, add it to your `modules` array in `nuxt.config.ts`:

```ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/fontaine']
})
```

Optionally, you can also add some configuration options if you like:

```ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/fontaine'],
   fontMetrics: {
     fonts: ['Inter', { family: 'Some Custom Font', src: '/path/to/custom/font.woff2' }],
   },
})
```

And that's it! By following these simple steps, you can improve the CLS (and overall performance) of your website. 

## Bonus

I usually like to know how the tool works so that I can understand better whether I need it or not. Let's dive deeper into the code to understand what is going on under the hood.

Let's say, that we want to use the following "Roboto" `font-face` declaration in our app:

```css
@font-face {
  font-family: 'Roboto';
  font-display: swap;
  src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff');
  font-weight: 700;
}
```

The `fontaine` module will generate for us the following code:

```css
@font-face {
  font-family: 'Roboto override';
  src: local('BlinkMacSystemFont'), local('Segoe UI'), local('Roboto'), local('Helvetica Neue'),
    local('Arial'), local('Noto Sans');
  ascent-override: 92.7734375%;
  descent-override: 24.4140625%;
  line-gap-override: 0%;
}
```

So basically, the module will scan your @font-face rules and generate fallback rules with the correct metrics.

Then, whenever you use font-family: 'Roboto', the module will add the override to the font-family, so instead:

```css
:root {
  font-family: 'Roboto';
}
```

We will get the following code in the final bundle:

```css
:root {
  font-family: 'Roboto', 'Roboto override';
}
```

## Summary

Well done! You have just managed to improve the overall performance of your website by using Fontaine and font-face override. Keep in mind however, that this is only the tip of the Iceberg in terms of improving performance so make sure to check out other articles and materials to make your app rapidly fast!