You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This first problem I fixed was one call to console.log would generate one message send the main page
which would update the array of messages and trigger a redraw by react.
This had the issue that if you log a bunch of strings as in for (let i = 0; i < 10000; ++i) { console.log(i); } each of those 10k strings sent a message and each message trigger a re-draw which resulted in it taking minutes to actually display those messages.
That was fixed by batching the messages and throttling sending them.
A new issue remained, if you issue 10k calls to log like the example above the throttling above still prevents any messages from getting displayed until JavaScript yields because the browser is single threaded so the setTimeout for used for throttling can't actually get processed until JavaScript yields. In other words you have this
for (let i = 0; i < 10000; ++i) {
doSomethingThatTakesTime()
console.log(i);
}
Assume it takes 10 seconds for that loop to end, nothing gets displayed in the log because the throttling of messages is based on setTimeout and JavaScript will not process the more events until the currently running event exits
I tried to fix that by adding a 2nd throttle which uses performance.now to see if some time as passed and if so to flush the queued messages
This seems like it would in Chrome AFAIK because Chrome will run the iframes from another domain in another process. Unfortunately, the host for the runner is in the same domain so it can't process messages until it's iframe yields. In other words this is the current structure
Because user-jsgist.html is on the same domain as runner.html they run in the same process so runner.html will not process any messages until user-jsgist.html yeilds
I could try to put user-jsgist.html in it's own domain but that would leave problem #3
Problem #3, no calls to console.log = no processing
Solution #2 attempted to let the code send messages even if the code does not yield by using performance.now to check if our time limit has passed and if so, sending the queued messages. This though is dependent on calling console.log. If you did this
You'd not see the message until 10 seconds have passed because there are no more calls to console.log for it to check
AFAIK the only real solution is to use a worker, send the messages to the worker, the worker won't sleep so it can do the throttling. I'm not sure that's a good solution or not. For it to work the user's process would have to send one message at a time (no queuing). The queuing would happen in the worker.
I have no yet implemented this solution
The text was updated successfully, but these errors were encountered:
It's surprising how deep this whole is
Problem 1: one log -> one msg -> one update
This first problem I fixed was one call to console.log would generate one message send the main page
which would update the array of messages and trigger a redraw by react.
This had the issue that if you log a bunch of strings as in
for (let i = 0; i < 10000; ++i) { console.log(i); }
each of those 10k strings sent a message and each message trigger a re-draw which resulted in it taking minutes to actually display those messages.That was fixed by batching the messages and throttling sending them.
8ce6e46
Problem 2: no yield = no processing setTimeout
A new issue remained, if you issue 10k calls to log like the example above the throttling above still prevents any messages from getting displayed until JavaScript yields because the browser is single threaded so the
setTimeout
for used for throttling can't actually get processed until JavaScript yields. In other words you have thisAssume it takes 10 seconds for that loop to end, nothing gets displayed in the log because the throttling of messages is based on
setTimeout
and JavaScript will not process the more events until the currently running event exitsI tried to fix that by adding a 2nd throttle which uses
performance.now
to see if some time as passed and if so to flush the queued messagesd99ded4
This seems like it would in Chrome AFAIK because Chrome will run the iframes from another domain in another process. Unfortunately, the host for the runner is in the same domain so it can't process messages until it's iframe yields. In other words this is the current structure
Because
user-jsgist.html
is on the same domain asrunner.html
they run in the same process sorunner.html
will not process any messages untiluser-jsgist.html
yeildsI could try to put
user-jsgist.html
in it's own domain but that would leave problem #3Problem #3, no calls to console.log = no processing
Solution #2 attempted to let the code send messages even if the code does not yield by using
performance.now
to check if our time limit has passed and if so, sending the queued messages. This though is dependent on callingconsole.log
. If you did thisYou'd not see the message until 10 seconds have passed because there are no more calls to
console.log
for it to checkAFAIK the only real solution is to use a worker, send the messages to the worker, the worker won't sleep so it can do the throttling. I'm not sure that's a good solution or not. For it to work the user's process would have to send one message at a time (no queuing). The queuing would happen in the worker.
I have no yet implemented this solution
The text was updated successfully, but these errors were encountered: