Improving Performance of Nuxt apps with Partytown
Tags: performance, javascript, tutorial, programming
Published: 2022-10-24 07:57:57

Partytown is a JavaScript library that helps relocate resource intensive scripts (often third-party scripts) into a web worker and off the main thread. This speeds up our site by freeing up the main thread to run our code.

Web Workers are a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface. In addition, they can perform I/O using XMLHttpRequest (although the responseXML and channel attributes are always null) or fetch (with no such restrictions). Once created, a worker can send messages to the JavaScript code that created it by posting messages to an event handler specified by that code (and vice versa).

![Web Workers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufch0g1of6l1rhvhpz7t.png)

If you would like to learn more about Web Workers, check out [here](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)

The main thread is where a browser processes user events and paints. By default, the browser uses a single thread to run all the JavaScript in your page, as well as to perform layout, reflows, and garbage collection. This means that long-running JavaScript functions can block the thread, leading to an unresponsive page and a bad user experience.

![Main Thread](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6cvz631xj22vnt3zp94i.png)

If you would like to learn more about the main thread, check out [here](https://developer.mozilla.org/en-US/docs/Glossary/Main_thread)

Partytown does not get bundled with the rest of your site's JavaScript. Instead, it intentionally stays separate from your code so that it can run within a webworker.

## Plausibile - our 3rd party code to optimize

Plausible is lightweight and open source web analytics. No cookies and fully compliant with GDPR, CCPA and PECR. Made and hosted in the EU, powered by European-owned cloud infrastructure 🇪🇺

![Plausible](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bmwxcdz74l0tmqkaq2w2.png)

After registering and providing your domain you will get a script code similar to the one below:

```html
<script defer data-domain="nuxt-partytown.vercel.app" src="https://plausible.io/js/plausible.js"></script>
```

In the next section we will be optimizing this script by using Partytown.

## Code

At any point, if you will feel lost, check out the GitHub repository that I have prepared for you https://github.com/Baroshem/nuxt-partytown.

I started form a plain Nuxt 3 project that should look more or less like this:

![Nuxt 3 project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ljulakx6j236yx9emmg6.png)

I will add the Plausible Script to the global `head` tag of our app:

```ts
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
    app: {
        head: {
            script: [
                {
                    defer: true,
                    src: 'https://plausible.io/js/plausible.js',
                    'data-domain': 'nuxt-partytown.vercel.app'
                }
            ]
        }
    }
})
```

And deploy our app to Vercel.

If we did all the steps correctly, we should see similar result in the browser dev tools:

![Plausible in the browser](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzxs66xrle9eya23iifk.png)

Now, we will move the script to the web worker by using the Partytown. To make it work we will use the official Nuxt module for the integration with the Partytown developed by Daniel Roe (Kudos to you Sir for the amazing work!).

To move our plausible script to the web worker we would need to add some configuration to our `nuxt.config.ts` file:

```ts
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
  modules: ["@nuxtjs/partytown"],
  partytown: {
    forward: ["$plausible", "$plausible.push"],
  },
  app: {
    head: {
      script: [
        { children: "window.$plausible = [];" },
        // Update this
        {
          src: "https://plausible.io/js/script.js",
          defer: true,
          type: "text/partytown",
          "data-domain": "nuxt-partytown.vercel.app",
        },
      ],
    },
  },
});
```

When we check the browser both our Nuxt app and the Plausible analytics, we can see that we are getting live data while our Plausible script is moved away from the main thread to the web worker.

![Plausible and Partytown in Nuxt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jfisxg25em0ftyl42c3p.png)

Also, when we compare our network tab in both cases we will also be able to see the result of moving the Plausible script to the web worker (the first tab is using Partytown, while the second is not):


![Network tab with and without Partytown](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/99s0q76bn1w4wtl2ez2g.png)

This approach works for many more 3rd party scripts that you can check out [here](https://github.com/nuxt-modules/partytown).

## Summary

Well done! You have just optimized your 3rd party scripts to make you Nuxt app more performant.

## Resources

* https://nuxt-partytown.vercel.app/
* https://github.com/Baroshem/nuxt-partytown
* https://dev.to/thisdotmedia/using-partytown-to-improve-the-performance-of-vuejs-applications-5bk6
* https://web.dev/workers-overview/
* https://developer.chrome.com/blog/inside-browser-part2/