DEV Community

loading...

Easy Web Worker integration in VueJS

Julien Calixte
Frontend & mobile developer in TypeScript/VueJS/React Native. Love building offline first PWAs. 🇧🇷🇫🇷🇪🇺
・2 min read

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 a 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
Enter fullscreen mode Exit fullscreen mode

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
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Finally we can use it this way:

  1. Create a file that ends with .worker.js and export async functions,
// utils.worker.js

export const helloWorld = async (params) => {
  // heavy computing goes here
}
Enter fullscreen mode Exit fullscreen mode
  1. Import them in vue files.
import { helloWorld } from '../workers/utils.worker'

export default {
  name: 'HelloWorld',
  data: () => ({
    msg: ''
  }),
  async mounted() {
    this.msg = await helloWorld()
  }
}
Enter fullscreen mode Exit fullscreen mode

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!

Discussion (4)

Collapse
vicentedl profile image
vicente-dl

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!

Collapse
jcalixte profile image
Julien Calixte Author • Edited

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.

Collapse
roynes profile image
Saitama

Hello!

Will this work without webpack? By just using the default mode?

Collapse
jcalixte profile image
Julien Calixte Author

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