Darren Xu Blog

How I Fixed a Slow Vue Application with Web Workers


Recently, I came across a challenging situation while working on a Vue application that grappled with slow data retrieval. In this blog post, I’ll share the issue I encountered while dealing with legacy code, the innovative solution I implemented using Web Workers, and the remarkable impact it had on boosting the application’s performance.

The Problem:

Our Vue application heavily relied on a hook that fetched data from an API. The hook utilized await on localforage, a library that interacts with IndexedDB, to retrieve data from the client-side database. However, this process had a noticeable impact on the application’s performance. Fetching data from IndexedDB could sometimes take up to 9 seconds, while retrieving it from the API directly took even longer – up to 14 seconds. Such delays were unacceptable, and it was clear that the data-fetching process needed an overhaul.

The Solution: Implementing Web Workers

To resolve the slow data retrieval issue, I decided to implement Web Workers. Web Workers are a powerful feature in modern browsers that enable parallel execution of tasks, freeing up the main thread and allowing for a more responsive user interface.

Bits of code I learnt:

Checking Web Worker Availability with Fallback: One essential consideration when working with Web Workers is to check if they are available in the user’s browser. While most modern browsers support Web Workers, some older versions might not. To ensure compatibility, I employed a simple feature detection technique:

// Checking if Web Workers are supported
if (window.Worker) {
  // Web Workers are available, proceed with creating workers
  // Your Web Worker code here
} else {
  // Web Workers not supported, provide a fallback mechanism
  // For example, you could handle the data retrieval directly on the main thread
}

Organizing the Web Worker in the src Directory: To fully leverage the benefits of modern JavaScript module systems, I found it beneficial to place the Web Worker code within the “src” directory alongside other Vue application files. This not only improved code organization but also allowed us to take advantage of the module resolution capabilities of modern bundlers like vite:

// Inside the Vue component where the Web Worker is used
const worker = new Worker('@/workers/dataRetrievalWorker.js', { type: 'module' });

By placing the Web Worker in the “src” directory and using the ”@/” alias, we ensured that it was treated as a module and could seamlessly import other modules from the application.

Using the “type: module” Argument on the Web Worker: One crucial aspect of working with modern JavaScript modules is specifying the “type: module” argument when creating a new Web Worker instance. This enables the use of ES6 import/export syntax within the Web Worker code, making it easier to organize and manage dependencies:

// Inside the dataRetrievalWorker.js (Web Worker) file
import localforage from 'localforage';
import axios from 'axios';

// Your Web Worker logic here