Skip to content

Partytown support #176

@luisherranz

Description

@luisherranz

Description

I'm opening this issue to discuss how WordPress could take advantage of Partytown to improve its performance.

What is Partytown?

Partytown is a library to execute scripts inside a Web Worker and off the main thread. Its main goal is to increase the site's performance freeing the main thread by offloading non-critical scripts to a Web Worker. It acts as a bridge between the Web Worker and the DOM in a way that is 100% transparent to the executed script.

How does Partytown work?

Scripts use the type "text/partytown" to avoid running in the main thread. Partytown loads those scripts inside a Web Worker that has a proxied version of all the DOM APIs. When the script access a DOM API, the proxy intercepts it and uses one of these two implementations:

  1. If Atomics are available, Partytown uses them to communicate synchronously between the main and worker thread.
  2. If they are not, Partytown uses synchronous XHR requests intercepted by a Service Worker.

If neither Atomics nor Service Workers are available, Partytown just runs the scripts in the main thread.

It's probably worth noting that when a script executed inside a Partytown Web Worker adds a new script (using APIs like document.createElement('script')), that script is also added inside of the Web Worker and not leaked to the main thread.

More information about how it works in their official docs.

Partytown tradeoffs

  1. DOM operations are slower (and even throttled to reduce work in the main thread), so it should not be used for intensive UI scripts.
  2. Partytown fetches all the scripts using fetch(), so they need to have CORS headers (or they need to use a proxy).
  3. Events handled by scripts that call event.preventDefault() will have no effect.

More info about the tradeoffs in their official docs.

Restricted access to DOM APIs

Because scripts executed with Partytown are sandboxed and it controls the bridge, site owners can increase the security/control over those scripts by allowing or denying access to the DOM APIs on a per-API basis.

I don't think Partytown has an API to control this yet, but they have mentioned it several times.

Partytown Status

Partytown is still a young project. It moved from Alpha to Beta on 5th Jan 2022.

Goals

  1. Allow plugin developers to execute scripts inside a Partytown Web Worker.
  2. Allow site admins to select which scripts they want to execute inside a Partytown Web Worker.

Proposals

1. Add a worker-partytown strategy on wp_enqueue_script

Following @adamsilverstein proposal of a strategy parameter on wp_enqueue_script (#168), plugin developers could simply opt-in to execute any script in a Partytown Web Worker by using the worker-partytown strategy.

wp_enqueue_script(
  'non-critical-script',
  plugins_url( 'non-critical-script.js', __FILE__ ),
  array(),
  '1.0.0',
  'worker-partytown'
);

There could be other worker strategies as well, so I'd suggest using worker-partytown for this one. For example worker-dom for WorkerDOM or simply worker for a regular Web Worker.

With this API, plugins could start offering the Web Worker option to their users:

Web Worker option in plugins

We could expose a filter to allow plugins to configure Partytown:

function my_plugin_partytown_config( $config ) {
  $config["debug"] = true;
  return $config;
}
add_filter( 'partytown_configuration', 'my_plugin_partytown_config' );
<script>
  partytown = {
    debug: true,
  };
</script>

2. Partytown module/plugin

Create a module that exposes a user interface to let the site admins configure which services they want to execute inside a Partytown Web Worker.

We could add integrations one by one, making sure Partytown supports those services. If necessary, it should also take care of configuring the forwarded events.

Integrations could use regular expressions to find the scripts in the HTML and add the type="text/partytown" attribute to the script tag. For example, identify scripts with https://www.google-analytics.com/analytics.js and/or ga(...) for Google Analytics.

<!-- Loaded in Partytown Web Worker -->
<script type="text/partytown">
  (function (i, s, o, g, r, a, m) {
    /* ... */
  })(
    window,
    document,
    "script",
    "https://www.google-analytics.com/analytics.js",
    "ga"
  );
  ga("create", "", "auto");
  ga("send", "pageview");
</script>

If this module is successful, we could export its functionality to a Partytown plugin.

Service Worker integration

We would probably want to integrate it with the PWA plugin and only add the Service Worker directly if the PWA plugin is not present.

Metadata

Metadata

Assignees

Labels

[Type] FeatureA new feature within an existing module

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions