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?
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.
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:
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.
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.
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.
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.
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
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...
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.
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
Top comments (0)