From f6e8cfd8d1b9d857cb2ccf4741bc9971e066ea5d Mon Sep 17 00:00:00 2001 From: Scott Newcomer Date: Thu, 24 Dec 2020 12:13:49 -0600 Subject: [PATCH 1/2] [Enhancement]: improve idle case with improved scrollTo under high loads --- addon/index.js | 80 ++++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 61 deletions(-) diff --git a/addon/index.js b/addon/index.js index 231bbdb7..9d450e55 100644 --- a/addon/index.js +++ b/addon/index.js @@ -10,50 +10,6 @@ const MAX_ATTEMPTS = 100; // rAF runs every 16ms ideally, so 60x a second let requestId; let callbackRequestId; -let idleRequestId; - -class CounterPool { - constructor() { - this._counter = 0; - this.onFinishedPromise = null; - this.onFinishedCallback = null; - - this.flush(); - } - - get counter() { - return this._counter; - } - set counter(value) { - // put a cap so flush queue doesn't take too many paint cycles - this._counter = Math.min(value, 2); - } - - flush() { - if (this.counter === 0 && this.onFinishedPromise && this.onFinishedPromise.then) { - // when we are done, attach a then callback and update scroll position - this.onFinishedPromise.then(() => { - this.onFinishedCallback && this.onFinishedCallback(); - }); - } - - idleRequestId = window.requestAnimationFrame(() => { - this.decrement(); - this.flush(); - }); - } - - decrement() { - this.counter = this.counter - 1; - } - - destroy() { - window.cancelAnimationFrame(idleRequestId); - this.counter = 0; - this.onFinishedPromise = null; - this.onFinishedCallback = null; - } -} /** * By default, we start checking to see if the document height is >= the last known `y` position @@ -65,12 +21,17 @@ class CounterPool { * @param {Object} scrollHash * @void */ -function tryScrollRecursively(fn, scrollHash) { - const body = document.body; - const html = document.documentElement; +function tryScrollRecursively(fn, scrollHash, element) { + let documentHeight; // read DOM outside of rAF - const documentHeight = Math.max(body.scrollHeight, body.offsetHeight, - html.clientHeight, html.scrollHeight, html.offsetHeight); + if (element) { + documentHeight = Math.max(element.scrollHeight, element.offsetHeight, element.clientHeight); + } else { + const body = document.body; + const html = document.documentElement; + documentHeight = Math.max(body.scrollHeight, body.offsetHeight, + html.clientHeight, html.scrollHeight, html.offsetHeight); + } callbackRequestId = window.requestAnimationFrame(() => { // write DOM (scrollTo causes reflow) @@ -172,8 +133,11 @@ class EmberRouterScroll extends EmberRouter { const element = document.getElementById(scrollElement.substring(1)); if (element) { - element.scrollLeft = scrollPosition.x; - element.scrollTop = scrollPosition.y; + let fn = (x, y) => { + element.scrollLeft = x; + element.scrollTop = y; + } + tryScrollRecursively(fn, scrollPosition, element); } } } @@ -201,18 +165,12 @@ class EmberRouterScroll extends EmberRouter { // out of the option, this happens on the tightest schedule scheduleOnce('render', this, CALLBACK, transition); } else if (scrollWhenAfterRender && !scrollWhenIdle) { - // out of the option, this happens on the tightest schedule + // out of the option, this happens on the second tightest schedule scheduleOnce('afterRender', this, CALLBACK, transition); } else { - if (!this.idlePool) { - this.idlePool = new CounterPool(); - } - - // increments happen all in one batch (before processing flush queue) and happens indeterminately - // e.g. 4, 6, 10 times this could be called - this.idlePool.counter = this.idlePool.counter + 1; - this.idlePool.onFinishedPromise = whenRouteIdle(); - this.idlePool.onFinishedCallback = this.updateScrollPosition.bind(this, transition); + whenRouteIdle().then(() => { + this.updateScrollPosition(transition); + }); } } } From 355b0137f1ab09395a305c4768b5ad3b3d1d1c58 Mon Sep 17 00:00:00 2001 From: Scott Newcomer Date: Thu, 24 Dec 2020 12:16:26 -0600 Subject: [PATCH 2/2] add param for Element --- addon/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/addon/index.js b/addon/index.js index 9d450e55..6236b0ce 100644 --- a/addon/index.js +++ b/addon/index.js @@ -19,6 +19,7 @@ let callbackRequestId; * @method tryScrollRecursively * @param {Function} fn * @param {Object} scrollHash + * @param {Element} [element] * @void */ function tryScrollRecursively(fn, scrollHash, element) {