The problem I'm having is the browser does not always show the "busy" indicator when it is supposed to.
Code below is TypeScript but that of course just becomes JavaScript. This uses kendo but other browser calls don't work either. I have tried just showing a busy gif, a jQuery busy plugin, even just added a little text to the html.
private demo() {
let that = this;
this.slowOperation(function () {
that.cpuIntensiveCode();
}, 20); // < 20 fails to show busy; >= 20 works, but > 50 is better
}
private slowOperation(fun: any, ms: number) {
kendo.ui.progress($(".spinner"), true);
setTimeout(() => this.callback(fun), ms);
}
private callback(fun: any) {
fun();
kendo.ui.progress($(".spinner"), false);
}
If I set the ms to 0 then the busy indicator isn't displayed even though it should be. Is this some kind of browser (Chrome/Firefox) bug? "slowOperation" returns on the current thread, so the browser has had it's chance to update the display before "callback" is called, but it doesn't do it for some reason.
How can I display a busy indicator, yet not have to force a small period of doing nothing? This delay is noticeable; in reality a lot of variability is in "cpuIntensiveCode" (my UI has a large number of user-selections and combinations) and it might be slow or it might be fast, so I do not want to add 20ms to it. Knowing how long it would take would be a bunch of code I don't want either. Just want the browser to do what it was told to do.
As there is only one thread, rendering of
is blocked, in theory there might/could be a callback from that method which would ensure that subsequent computation would happen after render finishes.
Basically you cannot expect rendering to be part of synchronous script execution. Surely you could cook something up with
requestAnimationFramebut callback from rendering method or Web Worker should instead be preferred I think.That 20 millisecond time you talk about just ensures that rendering of progress spinner finishes before computation starts.
I've come up with the same working jsfiddle which shows what you talk about and a solution with Web Worker which will execute CPU intensive code on a separate thread.
https://jsfiddle.net/ivarprudnikov/g3uktx9d/