To start, I'll say what party town is, in a nutshell: it's a tool to get some of your execution out of the main thread and into a worker.
It's doing that by communicating between the worker and the main thread, which will primarily execute DOM updates.
More in-depth, this concept works by you marking the scripts as `not javascript` then those scripts are forwarded to the worker. If those scripts are external, they must be passed through a proxy that will get around CORS.
Now most common use for PartyTown is for analytics scripts because they are heavy and can negatively affect performance; even the improved version of google tag manager has a large footprint. In fact, it could easily be the case that will cut 2-4% of your score. Now for that alone, and if you want to provide your user the highest amount of privacy, I feel that analytics should not be used.
But it may well be the case that you might need to use them for two main reasons; first, you see that data as absolutely critical, or second case which is mostly the case for me, you require that data by other services for gaining access to services that are otherwise not accessible.

The first step is to import the package. This will work in deno too by network import, depending on your case is either:
import { partytownSnippet } from 'https://cdn.jsdelivr.net/npm/@builder.io/partytown@0.7.5/integration/index.mjs'
or
import { partytownSnippet } from '@builder.io/partytown/integration'
On the client at the first execution point(+layout.svelte), you will invoke this function import:

//....
    let scriptEl: HTMLScriptElement
    onMount(
      async () => {
        if (scriptEl) {
          scriptEl.textContent = partytownSnippet()
        }
      }
    )
//....

Then in your <svelte:head> , you'll put the request interceptor forward param will contain an array of properties or nested properties that your third-party script might/will access.

<script>
        partytown = {
          forward: ['dataLayer.push'],
          resolveUrl: (url) => {
            const siteUrl = 'https://example.com/my-proxy'

            if (url.hostname === 'www.googletagmanager.com') {
              const proxyUrl = new URL(siteUrl + '/gtm')
    
              const gtmId = new URL(url).searchParams.get('id')
              gtmId && proxyUrl.searchParams.append('id', gtmId)
    
              return proxyUrl
            } else if (
              url.hostname === 'js.hcaptcha.com'
            ) {
              const proxyUrl = new URL(siteUrl + 'hcaptcha')
    
              return proxyUrl
            } else if (
              url.href.includes('google-analytics.com')
            ) {
              const proxyUrl = new URL(url.href.replace(url.hostname, 'example.com/my-proxy') + '/ga')
    
              return proxyUrl
            }
    
            return url
          }
        }
  </script>
<script bind:this={scriptEl}></script>

You'll also need to set up the Vite plugin for copying the PartyTown scripts as static assets, main line is:
partytownVite({
dest: join(process.cwd(), 'static', '~partytown')
}),

Notice the example.com/my-proxy in the resolveUrl this should be a URL pointing to a proxy that fetches the third-party scripts. On the cloud, you might use some native tools to create such a proxy, but I found those pretty lacking is just simple to make it directly in SvelteKit as an API route here, is an example:

import type { RequestHandler } from  './$types';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const respond = (body: any, type ="application/javascript", status = 200) => {
  return new Response(body, {
    status,
    headers: {
      'Content-Type': type,
    },
  });
};

export const GET: RequestHandler = async ({ url }) => { 
    if(url.href.includes('/pt/gtm')) {
      const fethUrl = 'https://www.googletagmanager.com/gtag/js' + url.href.replace(/.*?\/pt\/gtm.*?(\??)/gmi, '$1')
      const response = await fetch(fethUrl)
      const body = await response.text()
      return respond(body.replace(/https:\/\/.*?\.google-analytics\.com/gmi, '/pt/ga'));
    }
    if(url.href.includes('/pt/hcaptcha')) {
      const fethUrl = 'https://js.hcaptcha.com/1/api.js' + url.href.replace(/.*?\/pt\/hcaptcha.*?(\??)/gmi, '$1')
      const response = await fetch(fethUrl)
      return respond(response.body);
    }

    return new Response('Not found', { status: 404 });
}
  
export const POST: RequestHandler = async ({ url }) => {
  if(url.href.includes('/pt/ga')) {
    const fethUrl = 'https://www.google-analytics.com' + url.href.replace(/.*?\/pt\/ga/gmi, '')
    const response = await fetch(fethUrl, {
      method: 'POST',
      body: JSON.stringify({}),
      headers: {
        'Content-Type': 'application/json',
      },
    })
    return respond(response.body);
  }
  return new Response('Not found', { status: 404 });
}

You'll notice that when fetching the google tag manager script I replaced a host, with yet another proxy call this is because that URL can't be really easily intercepted. I tried and was not caught by a service worker for some reason; it might be invoked in a very hacky way inside the GTM script.


So this will effectively replace the host in the client script and will guarantee that no blockers can block your analytics collect script. So if you want to respect users' block choice, you would not do that; if you don't care, then I guess you can get better metrics, your choice.


In general, PartyTown is not suited for all kinds of scripts, for once scripts can behave differently or not work at all. All scripts will lose their native events like on load(which can be alleviated by checking the script attributes with a mutation observer). All events will be throttled( which is a good thing but might not fit your case) and will pass through messages before being handled.


And lastly, you can also use it to force ads on people without annoying them by putting nasty ad blockers. But don't forget the main primary use of PartyTown is to improve performance and get some well-suited execution done outside the main thread.

Tags

Related Articles

Github Contribution Table
Scrap / GET Contribution Table from GitHub

So when it comes to some products like Twitter &amp; GitHub, there are ways to either access non-public APIs or minimum, to scrap info that we can't take easily with the official API.For Twitter, I think it is more important because you can access a lot of dat...

Read more
tag cloud javascript
JS Tag Cloud derived from Wordpress

When I started to code this blog, I tried to extract from my WordPress blog some simple features that I think are essential. Now I don't know how crucial a `Tag Cloud`&nbsp;is, but I assume even if it is not central, nothing is more emblematic of a blog than a...

Read more
svelte blog
Made a SvelteKit blog that runs on Deno Serverless

Just converted and deployed this blog on Netlify. So I've been exploring svelte, and svelteKit, and I was looking to refresh my old blog that is in a neglected state. When I started this blog was 2007, and then it was of course, a WordPress blog, but I deleted...

Read more

EVM Signature