From 2268175a38f89030adfce8c213ebdbdfe0baad64 Mon Sep 17 00:00:00 2001 From: Thomas Nordquist Date: Mon, 14 Jan 2019 10:45:15 +0100 Subject: [PATCH] Fix performance issue When the root node was collapsed, it also was selected due to the click event. The sidebar was updated every time a new message was receivend, effectivly inhibiting the "render the tree if you got nothing else to do" optimization to render anything at all. Fixes #7 --- app/src/components/Sidebar/MessageHistory.tsx | 6 ++++-- app/src/components/Sidebar/NodeStats.tsx | 1 + app/src/components/Sidebar/Sidebar.tsx | 6 ++++-- app/src/components/Tree/Tree.tsx | 20 +++++++++---------- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/src/components/Sidebar/MessageHistory.tsx b/app/src/components/Sidebar/MessageHistory.tsx index 5a8d91b..6709bef 100644 --- a/app/src/components/Sidebar/MessageHistory.tsx +++ b/app/src/components/Sidebar/MessageHistory.tsx @@ -9,6 +9,8 @@ import Paper from '@material-ui/core/Paper' import Popper from '@material-ui/core/Popper' import ValueRenderer from './ValueRenderer' +const throttle = require('lodash.throttle') + interface Props { node?: q.TreeNode theme: Theme @@ -26,9 +28,9 @@ class MessageHistory extends React.Component { this.state = { } } - private updateNode = () => { + private updateNode = throttle(() => { this.setState(this.state) - } + }, 300) public componentWillReceiveProps(nextProps: Props) { this.props.node && this.props.node.onMessage.unsubscribe(this.updateNode) diff --git a/app/src/components/Sidebar/NodeStats.tsx b/app/src/components/Sidebar/NodeStats.tsx index 91ccc1b..5acac1c 100644 --- a/app/src/components/Sidebar/NodeStats.tsx +++ b/app/src/components/Sidebar/NodeStats.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import * as q from '../../../../backend/src/Model' + import { Typography } from '@material-ui/core' interface Props { diff --git a/app/src/components/Sidebar/Sidebar.tsx b/app/src/components/Sidebar/Sidebar.tsx index 6743419..7f2b334 100644 --- a/app/src/components/Sidebar/Sidebar.tsx +++ b/app/src/components/Sidebar/Sidebar.tsx @@ -22,6 +22,8 @@ import Topic from './Topic' import ValueRenderer from './ValueRenderer' import { connect } from 'react-redux' +const throttle = require('lodash.throttle') + interface Props { node?: q.TreeNode, classes: any, @@ -36,9 +38,9 @@ interface State { class Sidebar extends React.Component { private valueRef: any = React.createRef() - private updateNode = () => { + private updateNode = throttle(() => { this.setState(this.state) - } + }, 300) constructor(props: any) { super(props) diff --git a/app/src/components/Tree/Tree.tsx b/app/src/components/Tree/Tree.tsx index 824fa52..aff8797 100644 --- a/app/src/components/Tree/Tree.tsx +++ b/app/src/components/Tree/Tree.tsx @@ -9,12 +9,11 @@ import { connect } from 'react-redux' const MovingAverage = require('moving-average') -declare const performance: any -declare const window: any - const timeInterval = 10 * 1000 const average = MovingAverage(timeInterval) +declare var window: any + interface Props { autoExpandLimit: number didSelectNode?: (node: q.TreeNode) => void @@ -44,22 +43,26 @@ class Tree extends React.Component { return time } + private performanceCallback = (ms: number) => { + average.push(Date.now(), ms) + } + public throttledStateUpdate(state: any) { if (this.updateTimer) { return } const expectedRenderTime = average.forecast() - const updateInterval = Math.max(expectedRenderTime * 20, 300) + const updateInterval = Math.max(expectedRenderTime * 7, 300) const timeUntilNextUpdate = updateInterval - (performance.now() - this.lastUpdate) this.updateTimer = setTimeout(() => { - window.requestAnimationFrame(() => { + window.requestIdleCallback(() => { this.lastUpdate = performance.now() this.updateTimer && clearTimeout(this.updateTimer) this.updateTimer = undefined this.setState(state) - }) + }, { timeout: 500 }) }, Math.max(0, timeUntilNextUpdate)) } @@ -104,10 +107,6 @@ class Tree extends React.Component { cursor: 'default', } - const performanceCallback = (ms: number) => { - average.push(Date.now(), ms) - } - return (
{ collapsed={false} key="rootNode" lastUpdate={this.state.tree.lastUpdate} + performanceCallback={this.performanceCallback} />
)