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
This commit is contained in:
@@ -9,6 +9,8 @@ import Paper from '@material-ui/core/Paper'
|
|||||||
import Popper from '@material-ui/core/Popper'
|
import Popper from '@material-ui/core/Popper'
|
||||||
import ValueRenderer from './ValueRenderer'
|
import ValueRenderer from './ValueRenderer'
|
||||||
|
|
||||||
|
const throttle = require('lodash.throttle')
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
node?: q.TreeNode
|
node?: q.TreeNode
|
||||||
theme: Theme
|
theme: Theme
|
||||||
@@ -26,9 +28,9 @@ class MessageHistory extends React.Component<Props, State> {
|
|||||||
this.state = { }
|
this.state = { }
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateNode = () => {
|
private updateNode = throttle(() => {
|
||||||
this.setState(this.state)
|
this.setState(this.state)
|
||||||
}
|
}, 300)
|
||||||
|
|
||||||
public componentWillReceiveProps(nextProps: Props) {
|
public componentWillReceiveProps(nextProps: Props) {
|
||||||
this.props.node && this.props.node.onMessage.unsubscribe(this.updateNode)
|
this.props.node && this.props.node.onMessage.unsubscribe(this.updateNode)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import * as q from '../../../../backend/src/Model'
|
import * as q from '../../../../backend/src/Model'
|
||||||
|
|
||||||
import { Typography } from '@material-ui/core'
|
import { Typography } from '@material-ui/core'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import Topic from './Topic'
|
|||||||
import ValueRenderer from './ValueRenderer'
|
import ValueRenderer from './ValueRenderer'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
|
const throttle = require('lodash.throttle')
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
node?: q.TreeNode,
|
node?: q.TreeNode,
|
||||||
classes: any,
|
classes: any,
|
||||||
@@ -36,9 +38,9 @@ interface State {
|
|||||||
|
|
||||||
class Sidebar extends React.Component<Props, State> {
|
class Sidebar extends React.Component<Props, State> {
|
||||||
private valueRef: any = React.createRef<HTMLDivElement>()
|
private valueRef: any = React.createRef<HTMLDivElement>()
|
||||||
private updateNode = () => {
|
private updateNode = throttle(() => {
|
||||||
this.setState(this.state)
|
this.setState(this.state)
|
||||||
}
|
}, 300)
|
||||||
|
|
||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
super(props)
|
super(props)
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ import { connect } from 'react-redux'
|
|||||||
|
|
||||||
const MovingAverage = require('moving-average')
|
const MovingAverage = require('moving-average')
|
||||||
|
|
||||||
declare const performance: any
|
|
||||||
declare const window: any
|
|
||||||
|
|
||||||
const timeInterval = 10 * 1000
|
const timeInterval = 10 * 1000
|
||||||
const average = MovingAverage(timeInterval)
|
const average = MovingAverage(timeInterval)
|
||||||
|
|
||||||
|
declare var window: any
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
autoExpandLimit: number
|
autoExpandLimit: number
|
||||||
didSelectNode?: (node: q.TreeNode) => void
|
didSelectNode?: (node: q.TreeNode) => void
|
||||||
@@ -44,22 +43,26 @@ class Tree extends React.Component<Props, TreeState> {
|
|||||||
return time
|
return time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private performanceCallback = (ms: number) => {
|
||||||
|
average.push(Date.now(), ms)
|
||||||
|
}
|
||||||
|
|
||||||
public throttledStateUpdate(state: any) {
|
public throttledStateUpdate(state: any) {
|
||||||
if (this.updateTimer) {
|
if (this.updateTimer) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const expectedRenderTime = average.forecast()
|
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)
|
const timeUntilNextUpdate = updateInterval - (performance.now() - this.lastUpdate)
|
||||||
|
|
||||||
this.updateTimer = setTimeout(() => {
|
this.updateTimer = setTimeout(() => {
|
||||||
window.requestAnimationFrame(() => {
|
window.requestIdleCallback(() => {
|
||||||
this.lastUpdate = performance.now()
|
this.lastUpdate = performance.now()
|
||||||
this.updateTimer && clearTimeout(this.updateTimer)
|
this.updateTimer && clearTimeout(this.updateTimer)
|
||||||
this.updateTimer = undefined
|
this.updateTimer = undefined
|
||||||
this.setState(state)
|
this.setState(state)
|
||||||
})
|
}, { timeout: 500 })
|
||||||
}, Math.max(0, timeUntilNextUpdate))
|
}, Math.max(0, timeUntilNextUpdate))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,10 +107,6 @@ class Tree extends React.Component<Props, TreeState> {
|
|||||||
cursor: 'default',
|
cursor: 'default',
|
||||||
}
|
}
|
||||||
|
|
||||||
const performanceCallback = (ms: number) => {
|
|
||||||
average.push(Date.now(), ms)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={style}>
|
<div style={style}>
|
||||||
<TreeNode
|
<TreeNode
|
||||||
@@ -120,6 +119,7 @@ class Tree extends React.Component<Props, TreeState> {
|
|||||||
collapsed={false}
|
collapsed={false}
|
||||||
key="rootNode"
|
key="rootNode"
|
||||||
lastUpdate={this.state.tree.lastUpdate}
|
lastUpdate={this.state.tree.lastUpdate}
|
||||||
|
performanceCallback={this.performanceCallback}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user