question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Performance: Avoiding wasteful renders

See original GitHub issue

Use case

I’m adding interaction to a chart, so when the user hovers over the chart, the closes coordinate will “light up”.

Example

const data = [
  { x: 1502282820000, y: 0 },
  { x: 1502282880000, y: 480.07448979591834 },
  { x: 1502282940000, y: 210.27743589743585 },
  { x: 1502283000000, y: 437.2161836734694 },
  { x: 1502283060000, y: 178.02835999999996 },
  { x: 1502283120000, y: 462.68808163265305 }
];

class PerfTest extends Component {
  state = {
    markIndex: null
  };

  // Just pseudocode - not called anywhere 
  // this can be achieved with the Voronoi component, 
  // but is out of scope for this example
  onHover(index) {
    this.setState({
      markIndex: index
    });
  }

  render() {
    const { markIndex } = this.state;
    return (
      <XYPlot width={800} height={300} xType="time">
        <XAxis tickTotal={10} />
        <LineSeries xType="time" curve={'curveMonotoneX'} data={data} />

        {markIndex !== null && <MarkSeries data={[data[markIndex]]} />}
      </XYPlot>
    );
  }
}

Performance problem

When this.state.markIndex changes, PerfTest should re-render. However, I’ve noticed that every child of XYPlot also re-renders. In the example above, I would expect only MarkSeries to be re-rendered. Not XAxis or LineSeries.

Demo

I’ve created two demonstrations of the problem - one without optimizations, and the other with optimizations. Please allow 5 seconds for the performance test to run, and then check the results in the console.

Codepen without optimizations https://codepen.io/sqren/pen/WEYYLY?editors=0011

Total render time: 200ms Wasteful renders: 500 Wasted time: 270ms

Codepen with mutation optimizations https://codepen.io/sqren/pen/xLQmWL?editors=0011

Total render time: 140ms Wasteful renders: 250 Wasted time: 60ms

The optimized version makes half the amount of needless renders, and is 30% faster.

Question

I don’t think it’s a good approach to mutate properties, when passing them to child components. If the component is an instance of React.PureComponent it will not update correctly, so I expect weird results could come out of this.

On the other hand, I do like the performance gains in the optimized version. What is your take on this?

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:8
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

3reactions
akindrcommented, Aug 30, 2017

I’ve run into similar performance issues with implementing a crosshair on the chart. It’s particularly problematic in these spots, where the chart is expected to update at a high FPS but can’t keep up because it’s re-rendering lines, etc… that haven’t changed.

We worked around this by creating two charts that are positioned over each other - one for the crosshair and the other for the line series. Obviously that is a major hack!

It’d be nice if the individual series supported being pure components or even allowed a prop for comparison (say in the case of using Immutable for data storage, you might want to use Immutable.isEqual).

1reaction
JelleBlaauwcommented, May 13, 2019

I cannot believe this issue has not yet been picked up/resolved. The performance on a stacked bar chart with crosshair is dreadful when highlighting the render updates via the React dev-tools.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to identify and resolve wasted renders in React
This is where we will primarily put our optimization efforts. Configuring each component to only render and differentiate when it is necessary.
Read more >
Wasted Render : This can slow down our React App - Medium
It is called “wasted” render. This is really bad because there's really no reason for the entire component to be re-rendered when the...
Read more >
React Performance: Identifying Wasted Renders - YouTube
As your React app grows in size and complexity, you may be looking to find ways to improve performance. Luckily, there are many...
Read more >
Avoiding Wasted Renders in React Native App - Part 2
In the previous article, we saw 5 ways to avoid Wasted Renders in ... the impact these optimizations had on our application performance....
Read more >
how to check wasted renders in component react
Common optimisations you can do to prevent unnecessary renders include using PureComponent instead of Component, or use React.memo for ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found