How to use Web Worker with create-react-app

Michael Bykovski
2 min readNov 21, 2019

--

Web Workers

Create-react-app is a really nice library to get started with React. But as it comes to heavy computation power in your application you cannot use Web Worker without ejecting your create-react-app. This is painful because then you will have a lot of files and configurations lying around in your project.

Workerize-Loader

Workerize-loader helps to create Web Workers without ejecting your React application. https://github.com/developit/workerize-loader

Let’s start with:

create-react-app worker

Add workerize-loader to your application

yarn add workerize-loader

After that create your worker file:

# src/worker.jsexport const calculatePrimes = (iterations, multiplier) => {
while(true) {
let primes = [];
for (let i = 0; i < iterations; i++) {
let candidate = i * (multiplier * Math.random());
let isPrime = true;

for (var c = 2; c <= Math.sqrt(candidate); ++c) {
if (candidate % c === 0) {
// not prime
isPrime = false;
break;
}
}
if (isPrime) {
primes.push(candidate);
}
}
postMessage(primes);
}
}

Note that you cannot use console.log in your worker since it runs in a different thread.

Now extend your index.js by importing worker.js and creating an instance of the imported worker. Then you can use the basic Web Worker functions, as well as your implemented functions.

Consider to use: // eslint-disable-line import/no-webpack-loader-syntax

# src/index.jsimport React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
// Import your worker
import worker from 'workerize-loader!./worker'; // eslint-disable-line import/no-webpack-loader-syntax
// Create an instance of your worker
const workerInstance = worker()
// Attach an event listener to receive calculations from your worker
workerInstance.addEventListener('message', (message) => {
console.log('New Message: ', message.data)
})
// Run your calculations
workerInstance.calculatePrimes(500, 1000000000)
ReactDOM.render(<App />, document.getElementById('root'));

Surely you can initiate your worker anywhere else in the application. This was just an example.

Now you will see an additional thread in your browser running and it won’t block the default behaviour of your application:

Addition thread running in your browser

Have fun and happy coding! :)

--

--

Michael Bykovski

I am a full-stack developer at CompuTerra GmbH in Germany. Interested in decenralized networks, machine learning and just casual server-client applications.