From 0740dfde322ccb43aecb505c34c953015ba05cf3 Mon Sep 17 00:00:00 2001 From: Dave Coates Date: Fri, 9 Oct 2015 19:45:29 +1100 Subject: [PATCH] Performance optimisation Add shouldComponentUpdate for LogMonitorEntry to make it performant when triggering events rapidly such as onKeyDown. --- src/react/LogMonitor.js | 3 ++- src/react/LogMonitorEntry.js | 5 +++++ src/utils/shallowEqual.js | 27 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/utils/shallowEqual.js diff --git a/src/react/LogMonitor.js b/src/react/LogMonitor.js index c9839de5..969ede33 100644 --- a/src/react/LogMonitor.js +++ b/src/react/LogMonitor.js @@ -38,6 +38,7 @@ export default class LogMonitor extends Component { if (typeof window !== 'undefined') { window.addEventListener('keydown', ::this.handleKeyPress); } + this.handleToggleAction = this.handleToggleAction.bind(this); } static propTypes = { @@ -173,7 +174,7 @@ export default class LogMonitor extends Component { previousState={previousState} collapsed={skippedActions[i]} error={error} - onActionClick={::this.handleToggleAction} /> + onActionClick={this.handleToggleAction} /> ); } diff --git a/src/react/LogMonitorEntry.js b/src/react/LogMonitorEntry.js index e9edfb9c..ed4d79ac 100644 --- a/src/react/LogMonitorEntry.js +++ b/src/react/LogMonitorEntry.js @@ -1,6 +1,7 @@ import React, { PropTypes, Component } from 'react'; import JSONTree from 'react-json-tree'; import LogMonitorEntryAction from './LogMonitorEntryAction'; +import shallowEqual from '../utils/shallowEqual'; const styles = { entry: { @@ -23,6 +24,10 @@ export default class LogMonitorEntry extends Component { collapsed: PropTypes.bool }; + shouldComponentUpdate(nextProps) { + return !shallowEqual(this.props, nextProps); + } + printState(state, error) { let errorText = error; if (!errorText) { diff --git a/src/utils/shallowEqual.js b/src/utils/shallowEqual.js new file mode 100644 index 00000000..c70d564c --- /dev/null +++ b/src/utils/shallowEqual.js @@ -0,0 +1,27 @@ +export default function shallowEqual(objA, objB) { + if (objA === objB) { + return true; + } + + if (typeof objA !== 'object' || objA === null || + typeof objB !== 'object' || objB === null) { + return false; + } + + const keysA = Object.keys(objA); + const keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) { + return false; + } + + // Test for A's keys different from B. + const bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB); + for (let i = 0; i < keysA.length; i++) { + if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { + return false; + } + } + + return true; +}