How to use Web Worker with create-react-app
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:
Have fun and happy coding! :)