DEV Community

Cover image for Javascript "multithreading"
Mircea Sirghi
Mircea Sirghi

Posted on • Edited on

Javascript "multithreading"

Intro

Yes, limited, however, it can run code and render content in parallel. Contrary to widespread opinion that it can't. You see, Java is also single threaded if Threads are not used, isn't it?

Image description

I think that devs who have been using single-threaded JS for the whole career become deeply offended when somebody inaccurately mentions multithreading.

I have browsed a little bit on this subject and everybody who mentions JS is single-threaded omits to specify their source - always.

Image description

I have tried to find this proof in Ecma-international standard, with no success. Maybe I am looking in the wrong place? However, here is the formulation from Mozilla developers:

Image description

And mozilla source is recomended from Javascript-manual. So there are sources that discuss Threads in JS. And almost all sources mention Web Workers. This is what this article is about.

Image description

Web Workers

It took me a while to understand how Web Workers work. How they interact with main thread, and how main thread interacts with Web Workers. I need to confess, I am not a JS developer, however I create JS scripts occasionally.

So what is a web worker? It is just a Worker instance in JS that loads a script and runs it. Additionally it has an API that allows communication between main and worker threads.

To demonstrate how they work, I imagined the following scenario, I want to display content on a web page that is generated from different Workers in parallel, so that it is clear from the content which Worker generated it.

Basically I want to have a button "Start worker" and whenever I press it a new Worker is created and added to the Pool(map) of existing workers. When I press "Stop workers" all workers are closed and content is cleared.

Image description

Each time "Start worker" button is pressed a new Worker is created by loading worker.js and receiving a startup message composed of ["Worker name", "Start"].

All workers are closed by sending termination command to each worker ["Worker name", "Stop"], "Worker name" is not yet used while closing, however it may be useful to stop a particular worker, in the future.

Image description

The problem

Current browsers have a security CORS policy and don't allow for a script to be loaded from local machine, only from a Web Server. But I want this application to work without additional setup. Thus the solution I found was to load the worker.js file in an input field and from there to use it to instantiate Workers.

Image description

Demonstration

Open concurent/index.html in browser, load concurent/worker.js, press "Start worker" button a couple of times and observe how content is being generated

Image description

Conclusion

Even if Worker threads run in parallel, the listener is in main thread, which makes responses become queued. This invalidates the parallelism as the content is sequentially added. JS may have the capability for multithreading but limited to a concurent way when messages are passed from Workers to main thread. It is not possible to generate content in parallel. However, there is still a way to get parallelism...

Image description

Parallel Javascript

The only way to render content in parallel is through OffscreenCanvas. Pass the canvas handling to the worker thread and it will work in parallel with the main thread. A canvas can be attached to a worker only once. It is not possible to send the same canvas to multiple workers, though.

I have also learned a better way to load worker.js from here: Web.dev

Open parallel/index.html in browser, press "Start worker"/"Stop workers", observe how content is rendered in parallel.

Image description

Final conclusion

As I see it, it is not a limitation of JS, it is just how browsers currently render the DOM tree, it is not thread safe. Imagine some content being rendered at the same time with a worker changing or removing it. The obvious solution, or the easiest, so to speak, would be to make it thread safe by forcing synchronous acces. But this is how it currently works with a single thread. Even better, main thread never competes for getting access to the DOM tree. Here is a good resource to learn about it Developer.mozilla.org.

Repo

Code is available in Github

References

Ecma-international

Javascript-manual

Startbootstrap

Github

Web.dev

Developer.mozilla.org

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay