VueJS - Implementing a Dedicated Web Worker
In this article you will learn how to easily take advantage of multi-core CPU's by implementing a Dedicated Web Worker for you VueJS application.
Nevertheless, it provides some mechanisms that allow us to perform certain asynchronous operations and wait for their responses without blocking the main thread and, sometimes, the interface.
This article explains each one of these mechanisms.
There is not a way for us to do that asynchronously or even taking advantage of the multiple cores of our CPU. Well, at least, there wasn't.
With HTML 5 and modern web APIs, we are now capable of executing code that demands heavy processing without blocking the main thread and, consequently, the interface.
Today, I am talking about one of them: the Web Workers.
The official specification mentions three types of workers:
Wrapping things up:
Dedicated Workers are instantiated by the main process and can communicate only with it.
Shared Workers may be accessed by all processes executed in the same origin (different browser tabs, iframes or other shared workers).
Service Workers are event-oriented workers registered to an origin and a path. They are capable of controlling the website/page to which they are related, intercept and modify navigation and resource requests, and cache resources in a very granular way.
In this post, I am going to talk about how to implement a Dedicated Worker in a VueJS application and use it to take advantage of multi-core CPUs.
There are some ways to implement Web Workers within a VueJS project:
Using a plugin like vue-worker
Implementing a custom webpack configuration
Instantiating a Worker referencing a simple JS file (let's talk about this one 😆)
Implementing a Dedicated Web Worker in VueJS
1. Create a .js file inside the public folder;
2. Implement an onmessage function that receives an event as a parameter, process data* and, at the end of its execution, calls postMessage, passing the results as a parameter.
* The data passed as a parameter to this worker can be retrieved from event.data property
3. In a Vue Component, instantiate a new Worker and pass the absolute path of the recently created .js file as a parameter in its constructor.
4. Implement the functions onmessage and onerror according to your needs.
They are callbacks executed when the messages are received from the Worker and in case of any error, respectively.
5. Considering the problem you need to solve, create chunks from your data (you may use lodash/fp/chunk function) and iterate on them calling worker.postMessage passing the chunk as parameter.
The structure of both files will be similar to these:
Using this structure you will be able to instantiate a Web Worker, split the data into chunks and process each one of them asynchronously taking advantage of multiple threads and avoiding interface and browser freezing.
Obs.: I strongly suggest using ES5 code inside the worker.js file. By the time this article is being written, ES6+ code within Web Workers is still not fully supported by all browsers.
You can find a full example of this implementation in this repo.
Hope you liked it! Please, share.
Cover image by @helloimnik.