1

We all know we can spin up some web workers, give them some mundane tasks to do and get a response at some point, at which stage we normally parse the data and render it somehow to the user right.

Well... Can anyone please provide a relatively in-depth explanation as to why Web Workers do not have access to the DOM? Given a well thought out OO design approach, I just don't get why they shouldn't?

EDITED:

I know this is not possible and it won't have a practical answer, but I feel I needed a more in depth explanation. Feel free to close the question if you feel it's irrelevant to the community.

An0nC0d3r
  • 1,275
  • 13
  • 33
  • most cars have one steering wheel for a reason, think about it... if a lot of things were making changes, it would take a lot of work to sort all those cascading changes out, which would make for a slow layout. look into general concurrency issues for background info. – dandavis Oct 20 '15 at 22:24
  • 1
    It's a design choice. "Concurrency is **hard**", having to worry about dealing with locks and semaphores while bothering the DOM is just something that JavaScript does not want you to have to deal with. The question that @dave references goes into detail on why and in sufficient enough depth all things considered. – zero298 Oct 20 '15 at 22:36
  • I think this choice only helps to design MVC applications properly. – Tomáš Zato Oct 23 '15 at 18:51

3 Answers3

2

The entire world of Javascript in a browser was originally designed with a huge simplification - single threadedness (before there were webWorkers). This single assumption makes coding a browser a ton simpler because there can never be thread contention and can never be two threads of activity trying to modify the same objects or properties at the same time. This makes writing Javascript in the browser and implementing Javascript in the browser a ton simpler.

Then, along came a need for an ability to do some longer running "background" type things that wouldn't block the main thread. Well, the ONLY practical way to put that into an existing browser with hundreds of millions of pages of Javascript already out there on the web was to make sure that this "new" thread of Javascript could never mess up the existing main thread.

So, it was implemented in a way that the ONLY way it could communicate with the main thread or any of the objects that the main thread could modify (such as the entire DOM and nearly all host objects) was via messaging which, by its implementation is naturally synchronized and safe from thread contention.

Here's a related answer: Why doesn't JavaScript get its own thread in common browsers?

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
2

The other answers are correct; JS was originally designed to be single-threaded as a simplification, and adding multi-threading at this point has to be done very carefully. I wanted to elaborate a little more on thread safety in Web Workers.

When you send messages to workers using postMessage, one of three things happen,

  1. The browser serializes the message into a JSON string, and de-serializes on the other end (in the worker thread). This creates a copy of the object.
  2. The browser constructs a structured clone of the message, and passes it to the worker thread. This allows messaging using more complex data types than 1., but is essentially the same thing.
  3. The browser transfers ownership of the message (or parts of it). This applies only for certain data types. It is zero-copy, but once the main context transfers the message to the worker context, it becomes unavailable in the main context. This is, again, to avoid sharing memory.

When it comes to DOM nodes,

  1. is obviously not an option, since DOM nodes contain circular references,
  2. could work, but in a read-only mode, since any changes made by the worker to the clone of the node will not be reflected in the UI, and
  3. is unfortunately not an option since the DOM is a tree, and transferring ownership of a node would imply transferring ownership of the entire tree. This poses a problem if the UI thread needs to consult the DOM to paint the screen and it doesn't have ownership.
Igor Raush
  • 15,080
  • 1
  • 34
  • 55
0

Web Workers do not have DOM access because DOM code is not thread-safe. By DOM code, I mean the code in the browser that handles your DOM calls.

Making thread-unsafe code safe is a huge project, and none of the major browsers are doing it.

Servo project is writing new browser from scratch, and I think they are writing their DOM code with thread-safety in mind.

Aleksandar Totic
  • 2,557
  • 25
  • 27
  • It's not just a matter of "making the DOM thread safe". All Javascript programs that access the DOM would have to change their behavior to use the DOM in a thread safe manner or you'd have race conditions all over the place. Even something as simple as `if (domObj.prop === "foo") {domObj.prop = "fee";}` is a race condition if multiple threads can modify that object. – jfriend00 Oct 20 '15 at 22:39
  • This is incorrect. WebWorkers were a brand new feature, and older code that did not use WebWorkers would not have to change. The reason DOM calls in WebWorkers could not be made was because browser's DOM implementation could not deal with multiple threads. – Aleksandar Totic Dec 23 '15 at 06:39