I have a React page that asks for a user input for some info and returns an array of JSON objects from an API.
The query can return a large result causing in the page to freeze on loading the fetch, so I wanted to use a web worker to separate the threads and add a loading wheel to allow the user to know the site hasn't crashed.
I currently have my web worker with this code:
const self = this;
export default () => {
self.addEventListener('message', e => {
if (!e) return;
let query = e.data;
let res = null;
fetch(`https://statsapi.web.nhl.com/api/v1/schedule?startDate=${query}&endDate=${query}`)
.then(response => {
return response.json();
})
.then(function(_ref) {
postMessage(_ref);
});
});
};
This is just an example API, but the real API result would be much larger and take a longer time to load.
I am also using function(_ref)
instead of ({ data }) =>
because when processed through babel, ({ data }) =>
would be turned into _ref.data
when there is no data accessor through ref, and _ref
works at returning the array.
I have my code implemented in a web worker class like such:
export default class WebWorker {
constructor(worker) {
const code = worker.toString();
const blob = new Blob(['(' + code + ')()'], { type: 'text/javascript' });
return new Worker(URL.createObjectURL(blob));
}
}
I call the webworker in another class as such:
componentDidMount = () => {
this.worker = new WebWorker(worker);
}
getInfo = () => {
this.worker.postMessage(this.state.query);
this.setState(prevState => ({
...prevState,
open: true
}), () => {
this.worker.addEventListener('message', (event) => {
const res = event.data;
this.setState({
results: res,
open: false
});
});
});
}
The issue I have been running into is when I attempt calling it like I am, the web worker doesn't seem to be processing on another thread. The page still freezes even though the web worker is getting the data, as it still sets the state correctly after freezing.
I am new to web workers so is there something that I am missing that would allow it to work or would there be a different way of using a web worker with a fetch?
Comlink-fetch allows you to use Fetch in a web worker that is exposed through Comlink.
web workers help us to solve this problem, making our application dynamic so it loads faster. In this tutorial, we'll learn how to use web workers in a React application. We'll also learn how to use the useReducer Hook within a web worker with useWorkerizedReducer . Let's get started!
You can't use axios inside the worker because the blob that's created behind the scenes to load the worker. js runs in a different context than your main. js . In order for axios to work, you would have to setup a new webpack bundler to just bundle the worker by itself.
The first thing to do is to create the web worker using the Worker constructor. Then inside our button's event listener, we send a number to the worker using worker. postMessage({ num }) . After that, we set a function to listen for errors in the worker.
If your page is becoming unresponsive, that's an indicator that the main processing thread is being impacted by CPU-bound operations. I/O-bound operations, like fetching from a URL, would not impact your page's responsiveness, except for a bit of parsing overhead from the response. Therefore, the best usage of workers is to do CPU-intensive operations on a different thread. You gain very little (if anything) performance-wise moving I/O operations to workers.
Most likely, your rendering logic or data processing is what's causing things to hang, not the network request processing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With