-3

I am using Vite to build react application. And I have a js file with data (it is just a word dictionary). The file is big, its size is 28MB. Now it is imported and use in code directly. So built js file includes it and also has huge size. I wonder what if I create web worker, then import and use this dictionary file in web worker and just send data from worker to my code. Will code be split in that case and result js file with main code will be 28MB less, and js will load dictionary file after main code initialization?

1
  • No. This will not help in any meaningful way. The correct answer is to have the JS site only query what it needs as it needs it and keep the data on the server. Shipping 28 MB of data to the client is insane whether you do it in a web worker or not. Putting it in the web worker will actually be worse because sending data across the thread boundary in JS between the worker and the main thread will, with the exception of a shared byte buffer, result in a copy of the data being made. Commented Sep 10 at 11:20

1 Answer 1

0

You’re doing

import dictionary from "./bigDictionary.js";

Proplem

Vite sees this as a static import → so it bundles the dictionary into the main bundle.

Result: your main JavaScript file = React App + dictionary (28 MB).

If you move it to a Web Worker

The Web Worker file is built as a separate file in Vite.

When you do:

new Worker(new URL("./worker.js", import.meta.url))

Vite outputs worker.js as a separate file.

Any import inside worker.js (like your 28 MB dictionary) will be bundled into the worker file, not the main bundle.

Result:

Main bundle stays small (without the dictionary).

Worker bundle contains the dictionary.

The worker file is only downloaded when you create the worker.

So yes, this way the dictionary is separated from the main code.

// main.tsx
const worker = new Worker(new URL("./worker.js", import.meta.url), { type: "module" });

worker.postMessage("getDict");
worker.onmessage = (e) => {
  console.log("Dictionary received:", e.data);
};
// worker.js
import dictionary from "./bigDictionary.js";

self.onmessage = (e) => {
  if (e.data === "getDict") {
    postMessage(dictionary);
  }
};

Result:

index.js (main bundle, small)

worker.js (separate ~28 MB file, downloaded only when the worker is created)

Important notes

When you send a large object from the worker to the main thread → structured cloning happens (the browser makes a full copy of the object), which can be heavy for memory and performance.

Since the dictionary is 28 MB, it’s usually better to:

Keep it as a JSON file and fetch it only when needed:

const dict = await fetch("/dict.json").then(r => r.json());

Or store it in IndexedDB so it doesn’t reload every time.

If you need to run heavy searches or processing on the dictionary → then a worker is really useful.

Summary: Yes, moving the dictionary to a Web Worker makes Vite build it as a separate file and reduces the main bundle size. But if your only goal is to shrink the bundle, the simplest and more efficient solution is to keep the dictionary as a JSON file and fetch it instead of bundling it into your code.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. IndexedDB looks like a good idea for my case
I am happy to help you spend a nice time
The worker adds absolutely nothing here. You could fetch it on the main thread. In any case shipping 28 megabytes of data to a web page is nuts. Period. Don't give the OP enough rope to hang themselves with.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.