> For the complete documentation index, see [llms.txt](https://bimwhale.gitbook.io/ifc-js/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bimwhale.gitbook.io/ifc-js/web-worker-example/single-web-worker-example.md).

# 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`.&#x20;

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)](https://www.html5rocks.com/en/tutorials/workers/basics/). However, `Web Workers` makes it possible to run a script operation in a background thread [(2)](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).

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)](https://www.w3schools.com/html/html5_webworkers.asp).

### 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)](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers).

### I don't understand...

It's okay. Check out:

{% embed url="<https://www.w3schools.com/html/html5_webworkers.asp>" %}

## 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](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) when you [post a message](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage).

Certain types, say `Functions`, are **NOT** supported by the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/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](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/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`.

{% code title="examples/web-worker/main.js" %}

```javascript
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]);
}
```

{% endcode %}

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:

{% code title="examples/web-worker/worker/single-worker.js" %}

```javascript
onmessage = (e) => {
    const ifcData = e.data;
    const loaded = IFCjs.loadIfcFileItems(ifcData);
    const structured = IFCjs.constructProject(loaded);
    postMessage(structured);
};
```

{% endcode %}

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

#### Final Notes

Take a look at these commits:

* [Add Web Worker example](https://github.com/andrewisen/IFC.js-web-worker-example/commit/327abb2459a48fc468eabd1ee3b7a70c04fa6bba)
* [Add Config](https://github.com/andrewisen/IFC.js-web-worker-example/commit/f5d9ff76c9b90fa282eb88f1fc94b1bb3e8aa9e4)
* [Remove mainObject](https://github.com/andrewisen/IFC.js-web-worker-example/commit/d84a4864a8573c6d5cd2e67fef14439e701f453d)
