From d1620c3bcaf459d4c5d0471277cb2efdda97c5b2 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Tue, 30 Jan 2018 21:17:01 -0800 Subject: [PATCH] use rIC in pseudo virtual list --- package-lock.json | 5 +++ package.json | 1 + .../pseudoVirtualList/PseudoVirtualList.html | 12 ++++--- .../PseudoVirtualListItem.html | 32 +++++++++++++++++-- .../PseudoVirtualListLazyItem.html | 3 +- routes/_utils/scheduleIdleTask.js | 27 ++++++++++++++++ 6 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 routes/_utils/scheduleIdleTask.js diff --git a/package-lock.json b/package-lock.json index 006f73e..8b930f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7244,6 +7244,11 @@ "setimmediate": "1.0.5" } }, + "tiny-queue": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tiny-queue/-/tiny-queue-0.2.1.tgz", + "integrity": "sha1-JaZ/LG4lOyypQZd7XvdELvl6YEY=" + }, "tmp": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", diff --git a/package.json b/package.json index 5f43f8f..f039a99 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "svelte-loader": "^2.3.3", "svelte-transitions": "^1.1.1", "svgo": "^1.0.3", + "tiny-queue": "^0.2.1", "uglifyjs-webpack-plugin": "^1.1.5", "url-search-params": "^0.10.0", "webpack": "^3.10.0", diff --git a/routes/_components/pseudoVirtualList/PseudoVirtualList.html b/routes/_components/pseudoVirtualList/PseudoVirtualList.html index c179ab7..ed3cb40 100644 --- a/routes/_components/pseudoVirtualList/PseudoVirtualList.html +++ b/routes/_components/pseudoVirtualList/PseudoVirtualList.html @@ -7,7 +7,8 @@ makeProps="{{makeProps}}" key="{{wrappedItem.item}}" intersectionObserver="{{intersectionObserver}}" - hide="{{shouldHide(wrappedItem.item, $intersectionStates)}}" + isIntersecting="{{isIntersecting(wrappedItem.item, $intersectionStates)}}" + isCached="{{isCached(wrappedItem.item, $intersectionStates)}}" height="{{getHeight(wrappedItem.item, $intersectionStates)}}" /> {{/each}} @@ -35,7 +36,7 @@ let intersectionStates = this.store.get('intersectionStates') let keys = Object.keys(intersectionStates) for (let key of keys) { - intersectionStates[key].isIntersecting = false + intersectionStates[key].isCached = true } this.store.setForRealm({intersectionStates: intersectionStates}) @@ -60,8 +61,11 @@ } }, helpers: { - shouldHide(key, $intersectionStates) { - return !!($intersectionStates[key] && !$intersectionStates[key].isIntersecting) + isIntersecting(key, $intersectionStates) { + return !!($intersectionStates[key] && $intersectionStates[key].isIntersecting) + }, + isCached(key, $intersectionStates) { + return !!($intersectionStates[key] && $intersectionStates[key].isCached) }, getHeight(key, $intersectionStates) { return $intersectionStates[key] && $intersectionStates[key].rect.height diff --git a/routes/_components/pseudoVirtualList/PseudoVirtualListItem.html b/routes/_components/pseudoVirtualList/PseudoVirtualListItem.html index 0c3df6a..578b71a 100644 --- a/routes/_components/pseudoVirtualList/PseudoVirtualListItem.html +++ b/routes/_components/pseudoVirtualList/PseudoVirtualListItem.html @@ -1,9 +1,9 @@
- {{#if !hide}} + {{#if !shouldHide}} <:Component {component} virtualProps="{{props}}" virtualIndex="{{index}}" @@ -13,10 +13,38 @@
diff --git a/routes/_components/pseudoVirtualList/PseudoVirtualListLazyItem.html b/routes/_components/pseudoVirtualList/PseudoVirtualListLazyItem.html index 473d3e3..2ff50c5 100644 --- a/routes/_components/pseudoVirtualList/PseudoVirtualListLazyItem.html +++ b/routes/_components/pseudoVirtualList/PseudoVirtualListLazyItem.html @@ -5,7 +5,8 @@ :index :scrollToThisItem :intersectionObserver - :hide + :isIntersecting + :isCached :height on:scrollToPosition /> diff --git a/routes/_utils/scheduleIdleTask.js b/routes/_utils/scheduleIdleTask.js new file mode 100644 index 0000000..989fcc3 --- /dev/null +++ b/routes/_utils/scheduleIdleTask.js @@ -0,0 +1,27 @@ +// Wrapper to call requestIdleCallback() to schedule low-priority work. +// See https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API +// for a good breakdown of the concepts behind this. + +import Queue from 'tiny-queue' + +const taskQueue = new Queue() +let runningRequestIdleCallback = false + +function runTasks(deadline) { + while (taskQueue.length && deadline.timeRemaining() > 0) { + taskQueue.shift()() + } + if (taskQueue.length) { + requestIdleCallback(runTasks) + } else { + runningRequestIdleCallback = false + } +} + +export function scheduleIdleTask(task) { + taskQueue.push(task) + if (!runningRequestIdleCallback) { + runningRequestIdleCallback = true + requestIdleCallback(runTasks) + } +} \ No newline at end of file