GoogleChromeLabs / comlink

Comlink makes WebWorkers enjoyable.
Apache License 2.0
11.3k stars 386 forks source link

Use a single "message" event listener to dispatch received messages #653

Open achim-k opened 8 months ago

achim-k commented 8 months ago

From #649:

We make heavy use of Comlink for our WebWorker communication. On some recent profiling traces I noticed a hot-path on the "addEventListener" line.

292389350-2052be72-8671-4e20-9e06-fef0a30cb420

While its hard to say exactly how the event listeners are stored, most implementations I've seen for such interfaces involve storing them in an array and removing the listener equally requires adjusting an array. The existing logic also creates two closures - one for the Promise (which is unavoidable from what I can tell), and another for the event listener. As it was suggested in https://github.com/GoogleChromeLabs/comlink/issues/647 there is a potential for improvement by using a single "message" event listener and doing the dispatch manually by looking up the resolve functions in a Map.

This definitely reduces the runtime cost of the requestResponseMessage call itself - though there's still cost to new Promise and the closure. There's a shifted cost to the ID lookup on the map though in my profiling that did not show up as a hot path item.

Conceptually using a map for the lookup and one handler seems like it should perform better but if folks have some ideas on how to more robustly benchmark this PR that would be helpful.

This PR is similar to #649 and #651 but avoids that references to the resolve functions or the endpoint are kept in memory.

The performance impact of this PR gets more noticeable the more parallel requests are made: boxcompare

See also https://github.com/GoogleChromeLabs/comlink/pull/651#issuecomment-1899065317

google-cla[bot] commented 8 months ago

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

MikalDev commented 7 months ago

This change had a huge impact on my work with a physics library. I am calling a function on main thread to add physics bodies in the worker thread. Originally it was a huge hot path, because I was stress testing creating 5000 bodies in one 16ms tick.

I thought I would have to instead batch up the commands and parameters and send over in one message (which still might be a good idea), instead I can now continue to use the comlink proxy for the function. Nice work.

I am now using the foxglove fork for my project to pick up the other nice to haves like faster id generation.

lvivski commented 6 months ago

@achim-k Thank you for this change! I think the performance improvements are great. Do you still need to follow up on something or at this point are just waiting for the final PR approval?

achim-k commented 6 months ago

@achim-k Thank you for this change! I think the performance improvements are great. Do you still need to follow up on something or at this point are just waiting for the final PR approval?

This is just waiting for the final approval. We are already using this in production for a couple of months, without issues.

lvivski commented 6 months ago

@surma is this PR still interesting from the maintainer's perspective? I understand that you might have different opinions on how this should be implemented. I think this is a useful change for high-throughput applications.

ivancuric commented 3 months ago

Bump

ThaUnknown commented 2 weeks ago

is there any ETA for this? with this comlink could be adapted for use with generic message channels, such as websocket, text, etc and no longer be bound to just web workers

ivancuric commented 2 weeks ago

Comlink is abandonware. I use forks for now but will probably migrate to transporter or some other library.

On Mon, 16 Sept 2024, 17:02 Cas_, @.***> wrote:

is there any ETA for this? with this comlink could be adapted for use with generic message channels, such as websocket, text, etc and no longer be bound to just web workers

— Reply to this email directly, view it on GitHub https://github.com/GoogleChromeLabs/comlink/pull/653#issuecomment-2353179113, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVSGJ63U63QRSDERGZ46C3ZW3XIJAVCNFSM6AAAAABCBAGELOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNJTGE3TSMJRGM . You are receiving this because you commented.Message ID: @.***>