The SharedWorker Lifecycle Challenge in Single-page Navigation MPAs
Loading...
Syome Back to Posts

The SharedWorker Lifecycle Challenge in Single-page Navigation MPAs

A deep dive into maintaining SharedWorker state and connections during page transitions in MPAs

This article is mainly talking about how to maintain the connection of SharedWorker under single-page navigation MPA. If you are quite familiar with SharedWorker, you can click here to navigate to the key content.

About SharedWorker

SharedWorker is a web worker that can be shared between multiple windows. It is a powerful tool for building multi-page applications (MPAs). Here you can check out which browsers support it.

Can I Use SharedWorker

Advantages

SharedWorker provides several key benefits for multi-page applications:

  1. Shared State Across Pages: Unlike regular Web Workers which are tied to a single page, SharedWorker can maintain a single instance that multiple browser contexts (tabs, windows, iframes) can connect to. This enables efficient data sharing without relying on localStorage or cookies.

  2. Reduced Resource Usage: Since only one SharedWorker instance handles multiple connections, it reduces memory consumption compared to creating separate workers for each page. This is especially beneficial for resource-intensive tasks.

  3. Persistent Connections: SharedWorker maintains its state and connections even when individual pages are closed, as long as at least one page is still connected. This allows for continuous background operations like WebSocket connections.

  4. Improved Performance: By centralizing operations in a single worker, you can avoid duplicate requests or computations. For example, if one page fetches data, other pages can access the same data without making additional network requests. (For instance you can check out this post written by me)

SharedWorker vs. WebSocket (in the context of multi-page applications)

CapabilityWebSocket (per-page)SharedWorker + WebSocket
Connection CountEvery new tab opens its own WebSocket, so 10 tabs = 10 socketsExactly 1 socket for all tabs
Server Load10x sockets -> 10x file descriptors, 10x heart-beats, 10x auth hand-shakes1x socket -> 1x everything
Memory & CPUEach tab keeps its own buffers, timers, JS stateOne SharedWorker keeps one set of buffers & timers
Cold-start LatencyEach tab must re-authenticate and re-subscribe to channelsFirst tab does the work, later tabs inherit the ready connection
Data DeduplicationSame message is delivered N times (once per tab)Message arrives once inside SharedWorker and is broadcast locally
Offline/BackgroundTab dies -> socket diesTab dies but socket stays alive until the last tab closes

The killer advantage: SharedWorker turns an architecture that scales with the number of open pages into one that scales with the number of open browsers, slashing both client and server resource usage while keeping real-time responsiveness.


These advantages make SharedWorker particularly valuable for MPAs that need to maintain consistent state or share resources across multiple pages.

Disadvantages

Despite its benefits, SharedWorker comes with significant limitations, especially in MPA environments:

  1. Connection Dependency: The most critical limitation is that SharedWorker requires at least one active port connection to remain alive. In single-page navigation MPAs, when users navigate from one page to another, there’s a brief moment where no page is connected to the worker. This causes the SharedWorker to terminate instantly, losing all its state and benefits.

  2. Broken Persistent State: Because of the connection dependency issue, the advantage of persistent connections becomes unreliable in practice. Any data stored in the SharedWorker or ongoing operations will be lost during navigation between pages, making the single request benefit mentioned in the advantages section largely ineffective.

  3. Complex Lifecycle Management: Developers must implement complex connection management to ensure the worker stays alive during page transitions. This often requires keeping track of active connections and implementing workarounds that add significant complexity to the application.

These disadvantages make SharedWorker challenging to use effectively in traditional MPAs with page-based navigation, significantly limiting its practical applications.

As you can see, the mainly problem of this must be the Connection Dependency. If it is NOT necessary, choose multi-page navigation. That will simply keep SharedWorker alive. Or if so, dive into the following content.

Solution

I’ve spent a lot of time on this, it is just like an impossible task to adapt to most of the browsers.

Before this, I have tried using iFrame in this post but as it said, Avoid the use of iframe’s to display the full content. So this post will explor other solutions.

Since single-page navigation MPAs will terminate the SharedWorker when navigating locally, we need to find a way to keep the SharedWorker alive.

Prerequisites

Before diving into the solutions, it’s important to understand the conditions that must be met for SharedWorker if you are using single-page navigation MPA:

So the main implementation methods are still around this point:

The Simplest Implementation: Prerender

This is an Browser-internal optimisation hint.

Prerender is a browser feature that loads pages in the background before the user navigates to them, maintaining SharedWorker connections during page transitions.

How Prerender Works

Using

It is quite simple to use, just list all of your MPA pages in the prerender rules.

<script type="speculationrules">
{
  "prerender": [
    {
      "source": "list",
      "urls": ["page1.html", "page2.html", ...],
      "eagerness": "moderate"
    }
  ]
}
</script>

Note: Avoid using window.location.href='...' because it will trigger explicit navigation so that the SharedWorker will also be terminated. A <a href="..."></a> is recommended.

Advantages

Limitations

So, we haven’t checked out Can I Use yet.

Can I Use Prerender

As you can see, it is an experimental feature by Chromium and not widely supported. But the user base using Chromium-based browsers is up to 70%, so if you would not like to devote more time and energy to it, this is enough.


But I would not stop there.

Then I tried BFCache, idempotent message and so on, no one gave me the correct answer…

still exploring…