15

Chrome v83 enables JS module support for SharedWorkers → Starting a new era for...

 3 years ago
source link: https://medium.com/swlh/chrome-v83-enables-js-module-support-for-sharedworkers-starting-a-new-era-for-multi-browser-dbb20366bddf
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Chrome v83 enables JS module support for SharedWorkers → Starting a new era for multi Browser Window Apps with neo.mjs

Content

  1. The Chrome v83 release
  2. How is the support in Firefox and Safari?
  3. What is neo.mjs?
  4. Using SharedWorkers in neo.mjs
  5. What is the impact on using SharedWorkers?
  6. Is there a way to make this happen in Firefox & Safari now?
  7. What is coming next for neo.mjs?

The Chrome v83 release

https://www.chromestatus.com/features/schedule

Image for post
Image for post

You need to scroll to the very bottom:

Image for post
Image for post

https://www.chromestatus.com/feature/5169440012369920

Image for post
Image for post

A big thank you at the Blink Team for making this happen!

Now you might be wondering: “So, what does this mean?”

Since the release of Chrome v80, JS module support for “normal” workers is in place:

const worker = new Worker(filePath, {type: 'module'});

Now with v83, you can do this:

const sharedWorker = new SharedWorker(filePath, {type: 'module'});

Meaning: you can now use ES6+ classes & modules for your SharedWorkers, allowing us to create solid architectures for complex use cases.

2. How is the support in Firefox and Safari?

Truth to be told: not there yet.

Both, Firefox & Safari do not even support JS modules for non shared workers yet.

const worker = new Worker(filePath, {type: 'module'});

This will just break at the first (non dynamic) import statement.

(Opened 4 years ago)

(Opened 4 years ago)

In case you do care about Firefox & Safari not completely falling behind, please add some weight to the tickets. This should improve the priority.

What is neo.mjs?

neo.mjs is a webworkers driven UI framework I am working on. The first public release was on November 23, 2019.

The entire code base as well as all demo Apps are using the MIT license.

In short: neo.mjs is using 4 threads by default:

  1. Main (top level)

The main thread only creates the 3 workers, delegates virtualised UI events to the App worker and manipulates the real DOM (applying delta updates).

You can enhance Main using main thread addons, e.g. in case you want to work with external libraries like AmCharts or MapboxGL, which have to run inside the main thread.

Most parts of the framework as well as the Apps you build with it run inside the App worker.

This leaves the main thread mostly idle, leading to a blazing fast rendering performance.

To really get the idea, let us take a quick look at the Covid Dashboard Demo App without using SharedWorkers first:

Image for post
Image for post

MapboxGL is spawning some workers on its own. While workers can not access the DOM (window and window.document are undefined inside the worker scope), they can however directly access Canvas. So this is a good use case.

If you look at the console you will see the App, Data & Vdom workers.

Looking closer into the App worker:

Image for post
Image for post

Looking closer into the App worker (console), you will see that the Demo App is living there. This is the real code (JS modules & classes) without using source maps. You can work on your code base outside of nodejs. You don’t need any JS builds or transpilations to directly run it inside the browser.

4. Using SharedWorkers in neo.mjs

Since the neo.mjs architecture was specifically designed for this use case, I was able to create a first PoC with just very little changes:

https://github.com/neomjs/neo/commit/3ea3a7faad703aab4ffece3bef58bbe0dbb3bc1e

One thing i noticed when creating the PoC:

worker.port.addEventListener('message', me.onMessage.bind(me), false);

does not work, while you can use addEventListener() on a non shared worker. Might be worth a ticket. This change solved it:

worker.port.onmessage = me.onWorkerMessage.bind(me);

Let us take a look at the Demo App with using SharedWorkers again:

Image for post
Image for post

Console => you will notice that the App, Data & VDom workers are gone.

We need to open the following URL inside a new Browser Tab:

chrome://inspect/#workers
Image for post
Image for post

There we go. Let us inspect the shared App worker:

Image for post
Image for post

As you can see, our App no longer lives inside the browser tab, but inside the SharedWorker instead.

5. What is the impact on using SharedWorkers?

Now this is the part where it gets really exciting :)

As a start, we can now connect the Main Thread of multiple browser tabs to a shared App worker.

This does not only mean that multiple Apps only need to load the “big” part of the neo.mjs framework once, but they will live inside the same realm.

This is absolutely brilliant, since Apps can directly communicate to each other, without even needing to send post messages across workers.

It goes one step further: multiple Apps have access to the shared virtual DOM.

This enables us to unmount a component from one App and add it to another App which is running inside a different browser tab.

This will redefine the way to create Apps which are supposed to run on multiple screens at the same time.

The possibilities are countless: Think about dragging one UI dialog from one browser tab to another or selecting Grid rows in one tab and adjusting the content detail view in another browser tab.

You should also think about what this means in terms of scalability.

6. Is there a way to make this happen in Firefox & Safari right now?

In short: yes.

neo.mjs is using webpack to create dist versions which already work fine in Firefox & Safari.

We can convert our JS modules into “non modules”, which do work fine in other browsers than Chrome.

However, this will take a serious effort on creating the webpack chunks in a good way.

We need to split the chunks in a smart way: the app worker has to get an own chunk as the base and then we need to add the Apps which are supposed to work together and split their chunks for the modules that both are using.

We can probably just create new entry points which import the App worker directly and dynamically import the Apps we are going to use.

Help on this one would be appreciated!

7. What is coming next for neo.mjs?

I just finished the very first tutorial on how to create the Covid Dashboard App. This one got officially selected into “Javascript” by Medium and published by “The Startup”:

In case you want to learn how to use neo.mjs, it is definitely worth a look (it should take around 2 hours to walk through it).

I already started writing on Part 2, focussing on Collections / Stores, Routing and adding more views like Tables & the Helix into this App.

So, it will take a couple more days to finish it before I can dive deeper into adding full support for SharedWorkers. The idea is to add a new global framework config like “useSharedWorkers: {Boolean}”.

In case you want to use them, neo.mjs will need to map the different main thread ports to the Apps they are using and from there on, you can start to create multi display Apps.

To get the idea:

MyApp1.MainContainer.remove(component, false);
MyApp2.MainContainer.add(component);

As easy as this.

Feel free to add tickets into the issues tracker about features you would like to see:

https://github.com/neomjs/neo/issues

The project is in need for more contributors, so you are welcome to join in case you like open source.

Since this is definitely next level coding, your feedback on this topic would mean a lot to me!

Best regards,
Tobias


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK