DEV Community

Cover image for Improving Performance of Nuxt apps with Partytown
Jakub Andrzejewski
Jakub Andrzejewski

Posted on • Edited on

Improving Performance of Nuxt apps with Partytown

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

If you would like to learn more about Web Workers, check out here

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

If you would like to learn more about the main thread, check out here

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

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



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


Enter fullscreen mode Exit fullscreen mode

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

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



// 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'
                }
            ]
        }
    }
})


Enter fullscreen mode Exit fullscreen mode

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

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:



// 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",
        },
      ],
    },
  },
});


Enter fullscreen mode Exit fullscreen mode

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

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

This approach works for many more 3rd party scripts that you can check out here.

Summary

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

Resources

Top comments (9)

Collapse
 
iamdagy profile image
David Garcia

Hi, I haven't been able to get party town to work for GTM. I would appreciate your help.

this is the code im using in nuxt.config:

 app: {
        head: {
            viewport: 'width=device-width, initial-scale=1, maximum-scale=1',
            charset: 'utf-8',
            script: [
                {
                    src: 'https://www.googletagmanager.com/gtm.js?id=GTM-MYGTM',
                    async:true,
                    type: 'text/partytown'
                },
                {
                    hid: 'gtm',
                    innerHTML: 'window.dataLayer = window.dataLayer || [];(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({\'gtm.start\':new Date().getTime(),event:\'gtm.js\'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!=\'dataLayer\'?\'&l=\'+l:\'\';j.async=true;j.src=\'https://www.googletagmanager.com/gtm.js?id=\'+i+dl;f.parentNode.insertBefore(j,f);})(window,document,\'script\',\'dataLayer\',\'GTM-MYGTM\');'
                }
            ]
        },

    }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Hey hey,

Have you tried with this code from the github repository example?

github.com/nuxt-modules/partytown#...

Collapse
 
iamdagy profile image
David Garcia

Yes, and it doesn't seem to work.

Thread Thread
 
jacobandrewsky profile image
Jakub Andrzejewski

Hmm, can you report an issue in the GitHub repository of the partytown module?

Thread Thread
 
iamdagy profile image
David Garcia

Hi @jacobandrewsky, there is this issue github.com/nuxt-modules/partytown/... . But so far is still open and unresolved.

Collapse
 
awacode21 profile image
Annick Walkenhorst • Edited

with this solution how do i call push to push by javascript a custom click event?

Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Hey, I think the idea of handling event's does not change. This is only how the analytics is loaded on the page.

Collapse
 
awacode21 profile image
Annick Walkenhorst

but when i try to access $plausible or $plausible.push i always get undefined. That is why i am asking. when using this setup. How can i access plausible from nuxt?

Collapse
 
dd_nikita profile image
Nikita Denisov

А кто-нибудь подключал YandexMetrics?