DEV Community

Sachin Kasana
Sachin Kasana

Posted on • Originally published at javascript.plainenglish.io on

How Web Workers Saved My JavaScript App from Freezing on Every CSV Upload

A real-world performance fix that made my app usable again.

Ever uploaded a file and watched your app turn into a brick?

That’s what was happening in my dashboard app — a CSV visualizer that lets users upload massive spreadsheets, crunch the data, and generate real-time stats + charts.

It was working great… until people started uploading actual real-world CSVs.

  • 1 MB? Fine.
  • 5 MB? Kinda slow.
  • 20 MB? 🧊 Frozen UI. Zero response.

You clicked a button? Nothing.

Tried to scroll? Good luck.

Even the loader stopped spinning because… JavaScript was busy choking.

💡 Where It Went Wrong

JavaScript runs on a single thread.

That means any heavy CPU work (like parsing and summarizing CSV data) blocks everything else — buttons, scroll, animations, even paint.

I tried async/await. I tried debouncing. I tried optimizing my code like a maniac.

But the real problem?

My app was asking the main thread to do everything.

⚙️ What Was Happening Behind the Scenes

Every time a CSV was uploaded, I was doing this:

const reader = new FileReader();
reader.onload = (e) => {
  const text = e.target.result;
  const rows = parseCSV(text); // heavy loop!
  const stats = generateStats(rows); // CPU-heavy
  renderDashboard(stats); // React state update
};
reader.readAsText(file);
Enter fullscreen mode Exit fullscreen mode

Looks simple — but parseCSV and generateStats were brutal on big files.

React choked. The browser hung. The UI stopped responding.

🔥 Enter Web Workers

I needed a way to move all that heavy lifting off the main thread.

That’s where Web Workers come in — basically background threads for JavaScript.

They can’t touch the DOM, but they can do all the grunt work without blocking your UI.

🛠️ Step-by-Step: How I Refactored with Web Workers

📁 Create a worker file

// csvWorker.js
self.onmessage = function (event) {
  const csvText = event.data;
  const rows = parseCSV(csvText); // custom parser
  const stats = generateStats(rows); // summary metrics
  self.postMessage(stats);
};
Enter fullscreen mode Exit fullscreen mode

📥 Send work from your app

// inside App.jsx
const worker = new Worker(new URL('./csvWorker.js', import.meta.url), { type: 'module' });

worker.postMessage(csvText);

worker.onmessage = (e) => {
  const stats = e.data;
  setDashboardData(stats); // back on the main thread
};
Enter fullscreen mode Exit fullscreen mode

Boom. 🎯

The UI no longer froze. The spinner kept spinning. And users could scroll and click freely — even with 30MB CSVs uploading in the background.

🎉 The Results

Before Web Workers:

  • App froze for 3–5 seconds on every upload
  • Some browsers showed “Page is unresponsive” warnings
  • Rage-quits happened

After Web Workers:

  • Smooth, non-blocking experience
  • UI stays interactive while CSV is being parsed
  • Feels like a native desktop app now

🧠 Lessons I Learned

  • Web Workers are wildly underused. Especially for apps that deal with data-heavy processing.
  • They’re not hard to set up. Especially with modern tooling (Vite, Webpack, etc. support importing worker files natively).
  • You can’t share variables between threads. Use postMessage to send and receive data — no shared memory.
  • They work great with React. Just don’t try to touch DOM or React state inside the worker.

🔚 Final Thoughts

If your JavaScript app feels sluggish during file uploads, data crunching, or image processing — don’t blame React.

Blame the main thread.

Then give it a break — and let a Web Worker do the dirty work.

They’re not the most glamorous tool in the toolbox, but they might just save your app from performance hell.

🙌 Enjoyed the post?

If this helped you think differently about performance in JavaScript apps, drop a 👏 or leave a comment — I’d love to hear what you’re building or struggling with!

🧑‍💻 Check out more dev tools & blogs I’m working on:

📁 Portfolio → https://sachinkasana-dev.vercel.app

🔧 JSON Formatter Tool → https://json-formatter-web.vercel.app

Let’s keep making the web faster — one main thread at a time. 🚀

Thank you for being a part of the community

Before you go:


Top comments (0)