Brad Woods Digital Garden

Notes / JavaScript / Performance / Web workers

The Warhammer 40k Adeptus Mechanicus symbol

Table of contents

    A row of droids on display for sale

    Web Workers

    Planted: 

    Status: decay

    Hits: 248

    Running computationally expensive functions on a web page can make the page slow or stop responding (blocked). This is because the main thread running the UI (User Interface) also executes all the JavaScript. Being on 1 thread means the engine can only do 1 thing at a time. If the engine is executing an expensive function, it can't also respond to the user attempting to scroll a page.

    This can be solved by moving the execution of expensive functions to a different thread. The Web Workers API is a Web API that allows JavaScript to run in a background thread separate from the main execution thread. The worker constructor creates a web worker and returns an object that can send and receive messages.

    /index.js

    const myWorker = new Worker('myWorker.js');
    myWorker.postMessage('...');
    myWorker.onmessage = function (event) {};

    /myWorker.js

    onmessage = function (event) {};
    postMessage('...');

    Problem

    Imagine we created a 10 second timer. Every second, the count is outputted to the console.

    Expensive Function

    Now imagine we were required to execute an expensive function while the timer is running. To mock an expensive function, a while loop that runs for 3 seconds will be used.

    /index.js

    function expensiveFunc() {
    const laterMS = Date.now() + 3000;
    while (Date.now() < laterMS) {}
    }

    If you start the timer, then start the expensive function, you will notice the output is missing some numbers. When the counter has started, every second, the engine outputs a number to the console. When the expensive function is invoked, it starts executing the while loop. When it comes time to output the next number, the engine can't do it. It needs to 1st complete the while loop before it can continue with the counting.

    Solution

    A solution to this problem is to move the expensive function to a different thread using a worker:

    1. 1. Create a worker containing the function,
    2. 2. Send a message to the worker when the function need to be invoked,
    3. 3. Have the worker execute the function and
    4. 4. When complete, have the worker send back the results of the function.

    Now the count is no longer blocked when the expensive function is executed. Sandbox. A Web Worker can also be used within a React Component via the useRef hook. Sandbox.

    Feedback

    Have any feedback about this note or just want to comment on the state of the economy?

    Where to next?

    JavaScript
    Performance
    Arrow pointing downYOU ARE HERE
    A Johnny Cab pilot