Using a secondary thread does not promise us "parallel processing" - this will still be decided by the OS's scheduler. Even the existence of several CPU cores will not guarantee it (although it might increase the chances for it) - chances are that the work of the threads will be divided by "Time Slicing" - the scheduling concept in which each execution context gets X CPU time (where X is mostly in the area of milliseconds) until the current context is passed to the next one.
This is true for processes, for threads and for any kind of executions context that needs CPU time.The main difference between processes and threads is that threads share the same memory space, but within this memory space they can share data using message posting (or by using a concept similar to JS's
SharedArrayBuffer
and theAtomics
interface, which also uses a signaling mechanism between threads).The creation of a new thread: expensive. The fact you need to manage the data sharing between them: expensive. The fact you added more work to the OS's scheduler: expensive.
In the context of Javascript (i.e. Web Workers) - yes, you've gained a whole new "Event Loop", you've earned a whole new call stack (where there's usually only one). And yes, if you are inside a browser - it is a call stack devoid of DOM events, rendering events and other "system related" events - you get your own "clean" call stack. That's nice.
The only reason where you will want to offload data from the main thread to a secondary thread is when you might want to run some kind of "heavy" processing on the data - so heavy that it will block the main thread - thereby slowing-down your all system/process/browser.
You will still need to transfer/send data between the threads (e.g. via a messaging system), probably again and again: the unprocessed data from the main thread and, depending on the context, the processed data from the secondary thread to the main thread.
postMessage
is a short synchronous operation that puts an asynchronous callback with the data on the event loop of the other receiving thread's event loop.
Reminder
The whole event loop concept in Javascript (e.g. V8 runtime library) was developed to avoid the unnecessary creation of a new thread for every asynchronous thing, by using different queues for different async actions and a loop mechanism that knows how to pull those actions from them, again and again, between the "synchronous" operation runs.
Still, even the NodeJS event loop, might open a new thread when heavy computations are needed - such as reading a lot of data from an opened file.
Good examples for when to use a separate thread
Image processing
Audio processing
Compression
Encryption
Sometimes you might prefer offloading data to the GPU
The GPU has hundreds or thousands of cores capable of real parallel computing - these have a lot of limitations though (details about this are outside the scope of this article).
If it's graphics related - you are already free to make use of the WebGL API. If it's related to something more general you can use tools such as GPUJS or others.