Skip to content

Build1 publisher3 min readPublished

Moving the tag manager off the main thread costs a round trip per DOM call

INP reports the worst click of a visit. Third-party tags usually own it. Partytown runs those tags in a web worker, where every document.cookie read becomes a blocking message back to the thread you were trying to protect.

The Engineer · Build desk

Illustration accompanying Moving the tag manager off the main thread costs a round trip per DOM call

What happened

  • Google has measured Interaction to Next Paint as a Core Web Vital since March 12, 2024, timing the gap between a click, tap or key press and the next frame the browser paints.
  • INP takes every interaction in a visit and reports the worst, discarding the highest one for every 50 interactions, so a short session is scored on its single slowest click.
  • Partytown, a lazy-loaded library maintained by the QwikDev team, moves those third-party scripts off the main thread and into a web worker.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint The relocation covers script execution, not DOM access, so the gain depends on how rarely a tag touches the document; a layout-reading script arrives at the main thread as a queue of short tasks instead of one long one.
  • decision With the library in beta and compatibility decided script by script, adoption is a per-tag trial with a rollback path, not a one-line framework setting.
  • capability A vendor script written synchronously can run off the main thread without the vendor changing anything, because the proxy preserves the blocking API it expects.

A web worker has no DOM. There is no document and no real window inside it, and third-party scripts call document.cookie, getBoundingClientRect() and addEventListener as though there were [15]. Messaging between a worker and the main thread is asynchronous, while those scripts are written synchronously, with no await and no callback [16]. Partytown's answer is to build Proxies in the worker that look like window and document, forward each call to the main thread over a synchronous channel, and make the worker wait for the answer [17]. The post does not say how that channel is implemented [22]. From the script's side nothing changed.

What moves is parsing and execution. In the timeline the post draws, a tag manager takes 180 ms and a pixel 120 ms, both sitting ahead of the click handler [11]. The two add up to 300 ms [19], six times the 50 ms that makes a task a long task during which the browser cannot respond [20][10]. In the worker those long tasks still exist and nobody waits for them [18]. The proxied DOM calls are the part that stays: each one is a message the main thread has to service [17]. A script that reads a cookie and posts a beacon moves nearly all of its cost. A script that measures elements in a loop replaces one 180 ms task with a queue of short ones. A click that lands between two of those tasks still waits.

The scoring rule is what lets a third-party tail set the number. INP looks at every interaction in the visit and reports the worst, discarding the highest one for every 50 interactions [4]. On a landing page with six clicks, the discard rule never applies. The phase third parties inflate is input delay, the time before your handlers start because the browser is busy with something else [8]. FID timed only the first interaction's wait; INP times every interaction through to the next paint [6]. Only mouse clicks, touchscreen taps and key presses count, so scroll and hover never enter it [3].

According to the post, "you can write perfect code and still fail INP, because you share the road with scripts you don't control" [12]. That is the honest case for the library. The claim stops at that, and whether a given vendor script survives proxying stays open.

Partytown is a small lazy-loaded library maintained by the QwikDev team [13]. Its own warning is blunt. "It's not guaranteed to work for every script. Test before you ship," the post says [14]. Because the thresholds are read at the 75th percentile of your real users [5], the trial that settles it is a field comparison of the same pages before and after.

What to watch

  • Partytown leaving beta, or publishing a per-script compatibility list that names which tag vendors survive proxying.
  • Tag and pixel vendors shipping builds that run in a worker without needing window and document proxies at all.
  • A trace showing how many short main-thread tasks a proxied script generates, since each DOM call returns through the main thread.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories