about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNolan Lawson <nolan@nolanlawson.com>2017-05-26 05:05:52 -0700
committerEugen Rochko <eugen@zeonfederated.com>2017-05-26 14:05:52 +0200
commitb00cb2aed3634ad6624e144b99d538eb85c58c12 (patch)
tree2975b9811f64cf18e334734e74c202f20e0b69cb
parent7c67cb599713cfeec4bdcb5447f36718886da2be (diff)
Improve shouldComponentUpdate for status and status_action_bar (#3323)
-rw-r--r--app/javascript/mastodon/components/status.js37
-rw-r--r--app/javascript/mastodon/components/status_action_bar.js11
2 files changed, 39 insertions, 9 deletions
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index a1f52226f..5405ddfd1 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -44,6 +44,35 @@ class Status extends ImmutablePureComponent {
     isHidden: false,
   }
 
+  // Avoid checking props that are functions (and whose equality will always
+  // evaluate to false. See react-immutable-pure-component for usage.
+  updateOnProps = [
+    'status',
+    'account',
+    'wrapped',
+    'me',
+    'boostModal',
+    'autoPlayGif',
+    'muted',
+  ]
+
+  updateOnStates = []
+
+  shouldComponentUpdate (nextProps, nextState) {
+    if (nextProps.isIntersecting === false && nextState.isHidden) {
+      // It's only if we're not intersecting (i.e. offscreen) and isHidden is true
+      // that either "isIntersecting" or "isHidden" matter, and then they're
+      // the only things that matter.
+      return this.props.isIntersecting !== false || !this.state.isHidden;
+    } else if (nextProps.isIntersecting !== false && this.props.isIntersecting === false) {
+      // If we're going from a non-intersecting state to an intersecting state,
+      // (i.e. offscreen to onscreen), then we definitely need to re-render
+      return true;
+    }
+    // Otherwise, diff based on "updateOnProps" and "updateOnStates"
+    return super.shouldComponentUpdate(nextProps, nextState);
+  }
+
   componentWillReceiveProps (nextProps) {
     if (nextProps.isIntersecting === false && this.props.isIntersecting !== false) {
       requestIdleCallback(() => this.setState({ isHidden: true }));
@@ -52,14 +81,6 @@ class Status extends ImmutablePureComponent {
     }
   }
 
-  shouldComponentUpdate (nextProps, nextState) {
-    if (nextProps.isIntersecting === false && this.props.isIntersecting !== false) {
-      return nextState.isHidden;
-    }
-
-    return true;
-  }
-
   handleRef = (node) => {
     if (this.props.onRef) {
       this.props.onRef(node);
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js
index 5457dabac..064d841b8 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.js
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
 import IconButton from './icon_button';
 import DropdownMenu from './dropdown_menu';
 import { defineMessages, injectIntl } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
 
 const messages = defineMessages({
   delete: { id: 'status.delete', defaultMessage: 'Delete' },
@@ -21,7 +22,7 @@ const messages = defineMessages({
   unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
 });
 
-class StatusActionBar extends React.PureComponent {
+class StatusActionBar extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -43,6 +44,14 @@ class StatusActionBar extends React.PureComponent {
     intl: PropTypes.object.isRequired,
   };
 
+  // Avoid checking props that are functions (and whose equality will always
+  // evaluate to false. See react-immutable-pure-component for usage.
+  updateOnProps = [
+    'status',
+    'me',
+    'withDismiss',
+  ]
+
   handleReplyClick = () => {
     this.props.onReply(this.props.status, this.context.router);
   }