The main thread
Web workers are super handy to make heavy computation and not blocking the main thread. So the user doesn't have his webpage blocked by too much JavaScript working behind.
Example in VueJS
We can see how to use them easily in VueJS. Start by installing comlink-loader. Wait, what is Comlink? And comlink-loader?
Comlink is a library that simplify the way we call web workers, it will be as simple as calling an async function in our code. This lib was created by Surma.
comlink-loader is simply the webpack loader that we will use to tranform files *.worker.js
into web workers.
So here we go:
yarn add -D comlink-loader
Now, here's the trick to add the loader in your vuejs configuration. It is explained here.
module.exports = {
configureWebpack: (config) => {
config.module.rules = [
{
test: /\.worker\.js$/i,
use: [
{
loader: 'comlink-loader',
options: {
singleton: true
}
}
]
},
...config.module.rules
]
}
}
Finally we can use it this way:
- Create a file that ends with
.worker.js
and export async functions,
// utils.worker.js
export const helloWorld = async (params) => {
// heavy computing goes here
}
- Import them in vue files.
import { helloWorld } from '../workers/utils.worker'
export default {
name: 'HelloWorld',
data: () => ({
msg: ''
}),
async mounted() {
this.msg = await helloWorld()
}
}
Remember, it will always be async methods, so make sure to await them.
Set and done!
You can have a look at the quick example I've made to illustrate how web workers can impact user experience here: vue-worker-example.netlify.app. See if the button is clickable when the page is computing with and without background tasks.
Thanks for reading!
Top comments (4)
Great article that helped me a lot! one question though, how would you make a message back to the main thread? I have been trying to do MyWorker.onmessage but it gives me an error. Return would not be suitable for my app.
Thanks!
Hi Vicente! Thank you!
Do you want to receive a value from your service worker in you main thread? I think comlink hides the onmessage thing so you can return a value from a method in the web worker. Take a look at this example π
Just remember, methods in web worker will always return a promise.
Hello!
Will this work without webpack? By just using the default mode?
Hi!
I didn't tested but I guess it'll break after webpack bundles the app as the imported filename will not have the same name. I may be wrong