Single Web Worker Example

Introduction

This example is intended for beginners. However, I will assume that you have some basic knowledge about Web development, JavaScript and IFC.js.

Also, please note that this part is only an explanation of the concepts. Take a look at the next chapter (Developer Guide) to see step by step instructions.

Web Workers

What are Web Workers?

JavaScript is a single-threaded environment, meaning multiple scripts cannot run at the same time (1). However, Web Workers makes it possible to run a script operation in a background thread (2).

A Web Worker is a JavaScript script that runs in the background, independently of any other scripts, without affecting the performance of the page (3).

What can Web Workers do?

Web Workers are a simple means for web content to run scripts in background threads. Once created, a worker can send messages to the JavaScript code that created it by posting messages to an event handler specified by that code (4).

I don't understand...

It's okay. Check out:

Using Web Workers

How do I configure IFC.js to work with Web Workers?

Please note that Web Workers will not work straight out the box.

Web Workers use the structured clone algorithm when you post a message.

Certain types, say Functions, are NOT supported by the structured clone algorithm. Therefore, we cannot build the entire IFC Project in a Web Worker.

Why can't I build the entire IFC Project inside a Web Worker?

The mainObject, used in src/ifc-project-builder/ifc-structure-builder.js, contains some nasty stuff. The structured clone algorithm cannot deal with that type of object.

Also, it's hard to use Three inside a web worker. See: https://stackoverflow.com/a/52243600/14353202

How do I solve this?

I purpose that we (yes, you and me) use a dirty trick.

Let's:

  1. Start a Web Worker

  2. Run loadIfcFileItems() as usual

  3. Run constructProject() without the mainObject

  4. Exit the Web Worker

  5. Append the mainObject (outside of the Web Worker)

  6. Build the geometry (outside of the Web Worker)

Okay, so how do I actually do this?

I am glad you asked. Take a look at main.js.

examples/web-worker/main.js
function readFile(input) {
    const reader = new FileReader();
    reader.onload = () => {
        const ifcWorker = new Worker('worker.js');
        ifcWorker.postMessage(reader.result);
        ifcWorker.onmessage = function (e) {
          let structured = e.data; /
          structured.MainObject = mainObject;
          structured = buildGeometry(structured);
          scene.add(structured.MainObject);
        };
    };
    reader.readAsText(input.files[0]);
}

Notice how we use the Web Worker (line 5). We post the FileReader result into the worker. And, we get back the structured object (line 6).

Also, notice how we add back the mainObject in the snippet above.

Easy ey? :)

A closer look at the Web Worker

The code inside the Web Worker is actually super easy:

examples/web-worker/worker/single-worker.js
onmessage = (e) => {
    const ifcData = e.data;
    const loaded = IFCjs.loadIfcFileItems(ifcData);
    const structured = IFCjs.constructProject(loaded);
    postMessage(structured);
};

We simply mimic the beginning of the original loadIfc function, in src/IFC.js.

Final Notes

Take a look at these commits:

Last updated