about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorNolan Lawson <nolan@nolanlawson.com>2017-05-31 06:11:33 -0700
committerEugen Rochko <eugen@zeonfederated.com>2017-05-31 15:11:33 +0200
commit0e12a8dab9ccec83b91722a8b0a065c0919af98a (patch)
treeb8207645cca8285f845e0fac381581a14a56c8ed /app
parent3652a39de0d40acad1f2b170c74338b4fda01359 (diff)
Improve scheduling of requestIdleCallback tasks (#3477)
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/components/status.js3
-rw-r--r--app/javascript/mastodon/features/ui/util/schedule_idle_task.js29
2 files changed, 31 insertions, 1 deletions
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index d35642ede..2abe50f0b 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -14,6 +14,7 @@ import { FormattedMessage } from 'react-intl';
 import emojify from '../emoji';
 import escapeTextContentForBrowser from 'escape-html';
 import ImmutablePureComponent from 'react-immutable-pure-component';
+import scheduleIdleTask from '../features/ui/util/schedule_idle_task';
 
 class Status extends ImmutablePureComponent {
 
@@ -92,7 +93,7 @@ class Status extends ImmutablePureComponent {
     const isIntersecting = entry.intersectionRatio > 0;
     this.setState((prevState) => {
       if (prevState.isIntersecting && !isIntersecting) {
-        requestIdleCallback(this.hideIfNotIntersecting);
+        scheduleIdleTask(this.hideIfNotIntersecting);
       }
       return {
         isIntersecting: isIntersecting,
diff --git a/app/javascript/mastodon/features/ui/util/schedule_idle_task.js b/app/javascript/mastodon/features/ui/util/schedule_idle_task.js
new file mode 100644
index 000000000..b04d4a8ee
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/util/schedule_idle_task.js
@@ -0,0 +1,29 @@
+// 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;
+  }
+}
+
+function scheduleIdleTask(task) {
+  taskQueue.push(task);
+  if (!runningRequestIdleCallback) {
+    runningRequestIdleCallback = true;
+    requestIdleCallback(runTasks);
+  }
+}
+
+export default scheduleIdleTask;