about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNolan Lawson <nolan@nolanlawson.com>2017-09-30 05:28:49 -0700
committerEugen Rochko <eugen@zeonfederated.com>2017-09-30 14:28:49 +0200
commitca0e8be20cf35cce88b17e852448122219c0914f (patch)
tree9de4e8f69fe63ba0541b7694a64181d3e2246aca
parent83ffc4dc07cc619c166b36e2de0b0f0e7424d672 (diff)
Improve IntersectionObserverArticle perf (#5152)
-rw-r--r--app/javascript/mastodon/components/intersection_observer_article.js37
1 files changed, 21 insertions, 16 deletions
diff --git a/app/javascript/mastodon/components/intersection_observer_article.js b/app/javascript/mastodon/components/intersection_observer_article.js
index 575743350..e2ce9ec96 100644
--- a/app/javascript/mastodon/components/intersection_observer_article.js
+++ b/app/javascript/mastodon/components/intersection_observer_article.js
@@ -58,26 +58,31 @@ export default class IntersectionObserverArticle extends React.Component {
   }
 
   handleIntersection = (entry) => {
-    const { onHeightChange, saveHeightKey, id } = this.props;
+    this.entry = entry;
 
-    if (this.node && this.node.children.length !== 0) {
-      // save the height of the fully-rendered element
-      this.height = getRectFromEntry(entry).height;
+    scheduleIdleTask(this.calculateHeight);
+    this.setState(this.updateStateAfterIntersection);
+  }
 
-      if (onHeightChange && saveHeightKey) {
-        onHeightChange(saveHeightKey, id, this.height);
-      }
+  updateStateAfterIntersection = (prevState) => {
+    if (prevState.isIntersecting && !this.entry.isIntersecting) {
+      scheduleIdleTask(this.hideIfNotIntersecting);
     }
+    return {
+      isIntersecting: this.entry.isIntersecting,
+      isHidden: false,
+    };
+  }
 
-    this.setState((prevState) => {
-      if (prevState.isIntersecting && !entry.isIntersecting) {
-        scheduleIdleTask(this.hideIfNotIntersecting);
-      }
-      return {
-        isIntersecting: entry.isIntersecting,
-        isHidden: false,
-      };
-    });
+  calculateHeight = () => {
+    const { onHeightChange, saveHeightKey, id } = this.props;
+    // save the height of the fully-rendered element (this is expensive
+    // on Chrome, where we need to fall back to getBoundingClientRect)
+    this.height = getRectFromEntry(this.entry).height;
+
+    if (onHeightChange && saveHeightKey) {
+      onHeightChange(saveHeightKey, id, this.height);
+    }
   }
 
   hideIfNotIntersecting = () => {