I am facing challenges in efficiently transferring a large dataset (potentially more than a million items) generated in a Web Worker to the main thread in my Vue.js application. Currently, when I try to pass the generated grid from the worker to the main thread, it leads to errors such as "maximum call stack size exceeded" or even crashes the page.
Here's a simplified version of my current Web Worker code:
// gridWorker.js
self.onmessage = function (e) {
const { isUpdateColor, row, col, cellSize } = e.data;
if (isUpdateColor) {
const grid = Array.from({ length: row }, (_, i) => {
return Array.from({ length: col }, (_, j) => {
return {
i,
j,
code: `spot_${i}_${j}`,
// ... other properties
};
});
});
self.postMessage({ grid });
}
};
//main thread
<v-stage>
<v-layer ref="pathFinderLayer">
<div v-if="showTravelDistancePage">
<template v-for="rows in grid">
<v-rect v-for="(item, index) in rows" :key="item.code + '-' + index" :config="item"
@click="gridClick(item)" />
</template>
</div>
</v-layer>
</v-stage>
methods:
prepareGrid(isUpdateColor,cleanPath=true) {
this.gridWorker = new GridWorker();
this.gridWorker.onmessage = (event) => {
const { grid } = event.data;
this.grid = grid;
}
};
}
I suspect the issue arises from trying to pass such a large dataset to the main thread. Is there a more efficient way to handle this situation? Even when I pass partial data chunk by chunk, its still crash my page if the grid object is too many.
Approach 1: Generating on Main Thread
Initially, I attempted to generate the large grid directly on the main thread. However, this approach led to page crashes due to the sheer volume of objects.
Approach 2: Generating in Web Worker and Passing Entire Grid
To address the performance issues, I moved the grid generation process to a Web Worker. While this successfully offloaded the generation to a separate thread, passing the entire generated grid back to the main thread still resulted in page crashes.
Approach 3: Generating in Web Worker Chunk by Chunk
In the latest attempt, I opted to generate the grid in chunks within the Web Worker. I then passed each chunk individually to the main thread, storing the chunks inside the main grid. Unfortunately, this strategy also led to crashes at a certain point.
Seems XY problem. A short answer - you shouldn't do such things as generating a million items UI data. You should only generate data visible on the screen, that's called called a virtual scrolling. So you generate you data on the fly when needed.
If you still need to generate 1 million items ahead, do that in a worker and transfer only visible data on scrolling.
An example with a simple virtual list (it would even scroll much better). As you see I generate HTML on the fly (a more advanced scrolling would offset the top item imitating scrolling within an item too):