-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide an API in dedicate worker for executing event loop #10596
Comments
I'm not sure about the benefits from this seemingly synchronous API. The code will be paused, the JS execution will halt, the various queued tasks might be themselves executing async scripts / queuing new microtasks etc. But if we go back to the use-cases, it seems that indeed a recurring issue is that there is no way to intercept messages from the main thread synchronously. Maybe that should be tackled on its own. For instance, we could imagine an API that would expose the queued messages synchronously, along with a way to flush them synchronously. Though that still seems very exotic, I guess this is more workable with than breaking the event-loop concept. I'm not sure about the setTimeout case though, if one runs such a busy loop, they'll probably implement their own timer if needed. Also note that Footnotes
|
Currently, on my personal computer, awaiting a promise will let the JS engine to parse about 4 ms even the promise simply return null as a constant value. If a web game wants to reach 60FPS, the time for each frame is.only 16.6ms. 4ms will cause a 25% performance problem and this is inacceptable.
|
The 4ms delay is for reentrant timer tasks, i.e. for Awaiting a microtask also takes some time, I'm not denying it, but it will be in µs not ms. My point is that your proposal would also execute tasks and microtasks, and pause / switch / resume the execution scripts, which will take the same amount of time as if you just awaited the queued task. I don't think this proposal avoids what actually costs performance. |
The problem that why I don't want to use
This structure will make the JS engine halt for three times when invoking function2. In the real situation, this might cause much more pausing and resuming process and reduce performance. What about providing a dedicated await that only await the provided promise? like By the way, the problem here is not simply access the event queue from the main thread. |
OK. I found this API has already been provided but it doesn't belong to any API Standard. It's Maybe this is a bad implementation because it will take about 1ms and greatly relies on the implementation. |
Well after testing I found that |
I believe doing this to MessageEvents would need major changes to the specification of Javascript's event model itself. ECMA TC39 would be the venue for those changes, not WHATWG. Within the scope of APIs that WHATWG could standardize, this seems like it could be a situation that calls for a different type of inter-thread communication object entirely, unconnected to the existing message or stream APIs, with mostly SharedArrayBuffer-like semantics but a "queue" shape instead of an "array" shape. For a finite queue depth of easily serialized/deserialized messages, a SharedArrayBuffer can already be used for this. It seems to me that the specific cases that would need something more are two: (1) you can't calculate and reserve the maximum queue capacity in advance, or (2) serializing the messages into and out of bytes would be unacceptable overhead compared to structured cloning. I can imagine situations involving video frames where both of these cases are true simultaneously. |
Any suggestion for the place to submiting a feature request? Sorry I'm new to here :) |
What problem are you trying to solve?
Some of the codes require extremely high performance. Therefore, these codes will use Web Worker and make their codes like this:
Therefore, this Web Worker will never release the CPU and give the browser a chance to execute the event loop, which means, dozens of API, including
self.onmessage
,fetch
,OffscreenCanvas
cannot being used in this context.What solutions exist today?
For the developers of these applications, they will use
SharedArrayBuffer
to receive the messages from the main thread, as this API provide a way to transfer messages without releasing the CPU.They even use the XHR request and set
sync=true
to send a request to a ServiceWorker and transfer things back by catching this network request.Some people may argue that why they don't refactor there codes to something like this:
These codes will reduce the performance as each
executePart
will wait about 4 - 10 ms before getting execute.How would you solve it?
Adding an API like
processEventLoop()
for WebWorker only.This API can be invoked in any place in WebWorker. Once it's invoked, the browser will pause this JS code and execute things including
promise
,setTimeout
, event handle (onmessage
, ...).The codes will be like:
This API can also take one argument, which is a promise, like
let result = processEventLoop(fetch( ... ))
.This is like await, but it's not required to invoked in a async function.
(The problem that why we don't use async function is that this will also reduce performance)
Anything else?
These API are strange because they provide another way to execute a promise. It's like
OffscreenCanvasContext2D.commit()
, as this provides a solution without release the CPU.The text was updated successfully, but these errors were encountered: