Definitive guide to multi-threaded rendering on the Web

Use them multi core CPUs to speed up your web app.


During my Computer science graduate studies I took a ton of coursework dealing with threads, synchronization, race conditions, semaphores... aaand then ... I became a frontend engineer in 2013. The threads vanished, and I was left with the lonely main thread. Web workers were around, but not really.

But hey, its not 2013 any more!

Why do multi threaded rendering ?

The DOM is single threaded (still is, and might be forever). But we want to do more with it. Here are some cases where a single thread starts becoming a bottleneck:

  • Heavy data visualizations, dashboards with multiple visualizations

  • Apps with complex and sophisticated interaction patterns

  • Interactive infographics

  • Physics simulations

  • Low powered devices

What are my options?

Multi threading on the web can be classified into four broad categories:

  1. Compute only

  2. Prioritized scheduling

  3. Parallelized create DOM

  4. Parallelized create and mutate

    1. Canvas

    2. DOM

Lets take a closer look at each of these.

Compute Only

This is the traditional Web worker model. Compute on the client can be distributed to multiple Web Workers.

Implementations:

Prioritized scheduling

Work is rescheduled as per priority, giving a sense of a responsive application. Still uses a single thread.

Implementations:

Parallelized create DOM

  • Single compute thread (main thread)

  • The initial render load is shared by multiple workers.
    PS: The worker is generally a server side process.

Implementations:

Parallelized create and Mutate (Canvas)

With the new Offscreen canvas API (widely available since March 2023), you can create and control a canvas from a Worker. This brings us within striking distance from our goal, true multi-threaded rendering.

Implementations:

Parallelized create and mutate (DOM)

The DOM is both created and mutated by separate workers. There are two approaches which make this possible, and we will talk about the current implementations for each.

Web Worker w/ DOM

Worker DOM library implemented DOM within web workers, all the mutations are done within the worker and then periodically synced with the Main DOM. Checkout these slides for more details on how this works under the hood.

Parallel DOM via cross origin SubFrames

With the release of performance isolation in Chrome 88, its now possible to have multiple subframes (iframes) on a webpage which might be running in a separate process. The PDoM library tries to exploit this capability by providing an ergonomic abstraction (async postMessage, multiple iframe management etc).


That’s all folks!

What we didn’t talk about today is you could also use the above techniques in combination with one another. For eg, you could use the “Compute only worker threads” with “Parallelized create only” to achieve performance benefits beyond just the initial render.

Disclaimer: The author is the author of PDom.