Webworkers
JS is considered single-threaded which means jumping through hoops (e.g. using setInterval
) to avoid locking the UI when doing CPU intensive things.
webworkers are an answer to this. Each worker runs in their own thread (or as the specification puts it: "in the background") thus freeing the rendering loop. CPU intensive logic no longer blocks the UI.
In brief:
- they bring parallelism to JS
- they are well supported
- they use message passing rather than shared state which significantly simplifies concurrency (even if state needs to be copied)
Prior art
There is already prior art for using webworkers in ReasonML: http://davidgom.es/2017/12/23/reasonml-webworkers-bindings.html and I strongly recommend you read through it.
The author of that blog has also published bindings: https://redex.github.io/package/bs-webworkers.
Usage
All that is needed is:
- add them to our project (
yarn add bs-webworkers
) - add them to the
bs-dependencies
inbsconfig.json
- profit!
Gotchas
Distinct JS
It is important to note that the body of the worker should naively be its own source file. There are workarounds, such as using inline blobs, but both conceptually and literally, they are independent from your main application.
create-react-app
I struggled getting these to work in a project created with create-react-app
, primarily because by default all of the JS is bundled into a single file. There are a few threads worth reading on the create-react-app issue tracker and webpack has support for webpack loaders.
Getting that all wired up with create-react-app
with reason-scripts
was beyond me though.
That's all for now - short and sweet.
Resources
- https://www.w3.org/TR/workers/
- http://davidgom.es/2017/12/23/reasonml-webworkers-bindings.html
- https://github.com/webpack/webpack/tree/master/examples/web-worker
- https://www.html5rocks.com/en/tutorials/workers/basics/
- http://blog.nparashuram.com/2016/02/using-webworkers-to-make-react-faster.html
- https://medium.com/prolanceer/optimizing-react-app-performance-using-web-workers-79266afd4a7