Head of Exam Systems, Faria Education Group
5 October 2018
Photo from Reddit
Concurrency: multiple tasks run
It is possible to have concurrency on even a single thread.
Parallelism: multiple tasks run at the same time
True parallelism is not possible without multiple concurrently active execution
contexts, and can be extremely fragile in code written for Web applications.
Some Benefits of Parallelisation
Frees up the main thread to respond to user input, resulting in a snappier experience.
Additional executors might also be used to wrap otherwise synchronous operations,
as long as the underlying platform allows.
Better Utilisation of Resources
Additional execution contexts can better utilise available cores when there is a non-
trivial amount of work to be done on the client.
Parallelisation might have diminishing returns, because
parts of the work cannot be parallelised.
Essentially true for things that will be shown to the end user (in the UI).
Breaking work down into multiple pieces might
introduce additional overhead.
This results in a net increase of processing time and could make things worse!
Theoretical speedup is always limited by the part of the task
that cannot benefit from the improvement.
Amdahl’s Law 
(1 − p) + p
Photo by Wang Teck Heng from Pexels
Preemption vs Event-Driven
Single Context: setTimeout / Promise / Callbacks
No Parallelism. Event-driven. No pre-emption.
Multiple Contexts: Channel Messaging API
Parallelism. Preemption possible.
Command & Control
The script running in your Document (main execution
context) is responsible for managing the Control Flow.
It can spawn multiple execution contexts, or just
schedule work to be done.
It has to aggregate work results and present these to
the end user.
Example: Document + Worker
Example: Document + Frame
Each separate Execution Context needs to start
somewhere. They need to be seeded with work to be
done, and they need to convey the results back.
This is usually done with the Channel Messaging API
(postMessage calls and message events).
Data Movement in Messaging
The data may be any value or
the structured clone
algorithm, which includes
Data Movement in Messaging
An optional array of
Transferable objects to
transfer ownership of.
But bitmap support isn’t
Cancellation (Pre-Emption) of Unwanted Work
If the user no longer wants to do something, in-progress work can be cancelled.
Isolation & Handling of Errors
Instead of doing everything in a single Worker, consider a supervision tree, which
allows cleaner code, partial failures/restarts and general isolation of failures.
What if the Worker is stuck in a bad state or too busy to be cancelled?
Bad Example: the lone Worker
Design for Resiliency
Document Supervisor Checkpoints
> Any sufficiently complicated concurrent program in
another language contains an ad-hoc, informally-specified,
bug-ridden, slow implementation of half of Erlang.
Robert Virding 
Photo by Sharon McCutcheon from Pexels
Can the Problem be designed away?
Maybe the Problem should be dealt with server-side?
Can the Problem actually be dealt with concurrently?
Amdahl’s Law, etc. — maybe only parts of the Problem can be solved concurrently?
Additional complexity needs to be justified.
Divide & Conquer
Measure twice and cut once.
Be conscious of both execution and maintenance overhead.
Use Promises to manage control flow.
Resolve the appropriate Promise in message event handlers, to avoid nested
callbacks or other complications. Allows maintenance of a single-threaded illusion
— part affordance and part burden.
Photo by Little Visuals from Pexels
Demo 1: Sleep Sort
Messages are causally ordered and buffered.
What’s sent first will be received first. Busy workers cause buildup of messages.
Web Workers are not threads.
You can create many, many more Workers than the number of threads that a healthy
system is capable to support. System stability may suffer, though, and additional
Workers might block/fail on creation since Workers are implemented with Threads
which may be subject to quota.
Demo 2: Parallelisation Overhead
There is a mechanical cost to parallelisation
You need to spend time setting up and tearing down contexts, aggregating results, and
There is also a mental cost to parallelisation
At least in Web applications, parallelisation is not straightforward and usually carry
quite a big maintenance burden.
Demo 3: Error Isolation
iFrames are currently run within the same context.
Unlike Web Workers, there is no true isolation between the host document and its
iFrames. Chrome’s ongoing work on top-level document isolation is supposed to help
with this though.
Cancelling something is as important as running it
A Web application that can’t regulate itself is an app that goes “Aw Snap”.
Demo 4: Teasing the Compositor
Audio/Visual things are hard to parallelise
There is only one compositor per document at this time. Even in case of each iFrame
being driven from a separate process, composition is non-trivial.
Some things can’t be poly-filled
You can fake the illusion of a feature, like Offscreen Canvas, but reality catches up
with you, eventually. Sometimes it is never as good as native.
Demo 5: iFrame Spawnfest
If you really need to use iFrames, don’t draw anything
Even the simplest thing can slow down in great numbers.
Don’t use iFrames for concurrency
They are not isolated from each other. You can use multiple windows, though, as
long as the browser does not decide to offload or throttle background contexts.
Photo by Pixabay from Pexels
Reference: Slide & Code
“In the Loop” (2018). Singapore: JS Conf Asia. Conference Talk.
Examples shown. GitHub Repository.
MDN (Mozilla Developer Network) Web Docs.
Channel Messaging API.
The Chromium Projects
Chromium Security — Site Isolation.
Chromium Design Document — Site Isolation.
Living Standard for Web Workers.
Source Code Locations
Blink: See “Worker Code Locations” in Blink Workers.
Blink: Can’t start nested workers (#31666)
Photo of Bear Grylls.
Improvise. Adapt. Overcome.