UX: Improve loading-slider behavior (#29995)

- Use `requestAnimationFrame` when transitioning from `ready` -> `loading`. The previous `next()` implementation was unreliable, particularly in Safari, and would cause the loading slider to jump backwards instead of forwards

- Double the minimum transition time to 200ms. This avoids the rolling average being skewed too much by routes which load quickly without network access.
This commit is contained in:
David Taylor 2024-11-29 16:32:59 +00:00 committed by GitHub
parent 3cde55b76f
commit f20db92512
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 10 additions and 4 deletions

View File

@ -2,7 +2,7 @@ import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { cancel, next } from "@ember/runloop";
import { run } from "@ember/runloop";
import { service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import { eq } from "truth-helpers";
@ -23,12 +23,16 @@ export default class PageLoadingSlider extends Component {
willDestroy() {
super.willDestroy(...arguments);
this.loadingSlider.off("stateChange", this, "stateChange");
if (this._deferredStateChange) {
cancelAnimationFrame(this._deferredStateChange);
this._deferredStateChange = null;
}
}
@bind
stateChanged(loading) {
if (this._deferredStateChange) {
cancel(this._deferredStateChange);
cancelAnimationFrame(this._deferredStateChange);
this._deferredStateChange = null;
}
@ -36,7 +40,9 @@ export default class PageLoadingSlider extends Component {
this.state = "loading";
} else if (loading) {
this.state = "ready";
this._deferredStateChange = next(() => (this.state = "loading"));
this._deferredStateChange = requestAnimationFrame(() => {
run(() => (this.state = "loading"));
});
} else {
this.state = "done";
}

View File

@ -7,7 +7,7 @@ import { bind } from "discourse-common/utils/decorators";
const STORE_LOADING_TIMES = 5;
const DEFAULT_LOADING_TIME = 0.3;
const MIN_LOADING_TIME = 0.1;
const MIN_LOADING_TIME = 0.2;
const STILL_LOADING_DURATION = 2;