DEV Community

Cover image for Optimizing heavy operations in Vue with Web Workers
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

28

Optimizing heavy operations in Vue with Web Workers

Heavy computations on the main thread can lead to sluggish UI, dropped frames, and poor user experience. Fortunately, Web Workers allow us to offload intensive tasks to background threads.

In this article, we'll explore how to use Web Workers in a Vue 3 project to keep the UI responsive while running CPU-heavy tasks.

Enjoy!

🤔 Why Use Web Workers in Vue?

JavaScript is single-threaded, which means the main thread handles both UI rendering and logic execution. When you perform complex operations (e.g., image processing, data crunching, cryptography), it can block the main thread.

What is a Web Worker?
Source: https://web.dev/articles/workers-overview

Web Workers help by running such tasks in a separate thread that comes with benefits such as; keeping UI smooth and responsive, avoiding "frozen" interactions, and improving perceived performance.

When working with Web Workers, there are few best practices that we should follow:

  • Offload only CPU-intensive work: Don’t use workers for simple logic.
  • Terminate the worker after use: Prevent memory leaks.
  • Use transferable objects: For large binary data (ArrayBuffer), use transferables to avoid copying overhead.
  • Consider comlink: A small library that simplifies worker communication.

Remember that workers don’t have access to the DOM so if your heavy operation requires access to it, you should not use a web worker for that.

🟢 Creating a Web Worker in Vue 3

To use Web Workers, we will need to create a separate JavaScript file that the worker will run:

// src/workers/heavyTaskWorker.js
self.onmessage = function (e) {
  const input = e.data;

  // Example heavy computation: Fibonacci
  function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
  }

  const result = fibonacci(input);
  self.postMessage(result);
};
Enter fullscreen mode Exit fullscreen mode

Next, we would need to use the Worker in a Vue Component:

<script setup>
import { ref } from 'vue';

const number = ref(35);
const result = ref(null);
const loading = ref(false);

const runWorker = () => {
  loading.value = true;

  const worker = new Worker(new URL('@/workers/heavyTaskWorker.js', import.meta.url), {
    type: 'module'
  });

  worker.postMessage(number.value);

  worker.onmessage = (e) => {
    result.value = e.data;
    loading.value = false;
    worker.terminate();
  };
};
</script>

<template>
  <div>
    <label>Enter a number: </label>
    <input v-model.number="number" type="number" />
    <button @click="runWorker">Run Fibonacci</button>
    <div v-if="loading">Computing...</div>
    <div v-else-if="result !== null">Result: {{ result }}</div>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

When using Vite, workers can be loaded with new URL() syntax. Webpack and other bundlers may require different configuration.

Communication with a Web Worker is asynchronous and message-based:

  • worker.postMessage(data) sends data to the worker.
  • worker.onmessage = (e) => {} receives data back from the worker.
  • worker.terminate() stops the worker once it's done.

You can also handle errors with worker.onerror.

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

✅ Summary

Integrating Web Workers in Vue 3 helps manage performance bottlenecks caused by heavy computations. By offloading work to a background thread, you keep the UI fast and fluid, especially in data-intensive apps.

Take care and see you next time!

And happy coding as always 🖥️

Heroku

Amplify your impact where it matters most — building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (1)

Collapse
 
anandbaraik profile image
Anand-Baraik

Could you please add any real time scenario examples. It would be really helpful

Jetbrains Survey

Calling all developers!

Participate in the Developer Ecosystem Survey 2025 and get the chance to win a MacBook Pro, an iPhone 16, or other exciting prizes. Contribute to our research on the development landscape.

Take the survey

AWS Security LIVE!

Hosted by security experts, AWS Security LIVE! showcases AWS Partners tackling real-world security challenges. Join live and get your security questions answered.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️