phileras phileras - 1 year ago 102
Javascript Question

Avoid re-rendering on scroll and increase performance in a React web application

I having performance problems with React, basically I have 2 compact menus that appear when the page scroll to x distance from the top. As I see another components of the web application are doing little moves when I scroll, the cause is because they are re-rendering.

To know the distance to the top while a user does a scroll I have a eventlistener on the componentDidMount() and I think that this is causing the problem but I'm not sure, as you know react stable version is pretty new and I'm also new with this technology:

Here is some code, exactly the top bar where are nested components and triggers the compact menu bar to appear when user scolls more than 100px from top:

export default class AppTopBar extends Component {
constructor (props){
super(props);
this._bind("_handleOnScrollDocument");
this.state = {
StatusBar: false
}
}

componentDidMount() {
if (process.env.BROWSER) {
document.addEventListener("scroll", (e) => this._handleOnScrollDocument(e), true);
}
}

_handleOnScrollDocument(e) {
if (e.target.body.scrollTop > 100) {
this.setState({ StatusBar: true });
} else {
this.setState({ StatusBar: false });
}
}

render() {
return (
<div className="aui-core-apptopbar">
<StatusBar companies={this.props.companies} compactMenuItems={this.props.compactMenuItems} StatusBar={this.state.showCompactStatusBar}/>
<StatusBar companies={this.props.companies} userOptions={this.props.userOptions} compactMenuItems={this.props.compactMenuItems}/>
<MainNavBarView menuItems={this.props.menuItems}/>
</div>
);
}
}


I have been investigatin and reading info about the components lifecycle and other performance stuff like this: PURERENDERMIXIN

Do you know a better way to do things to get light web applications and avoid re-rendering on scroll?

Answer Source

Let's say you create a local variable flag for your class. And then:

_handleOnScrollDocument(e) {
  let newFlag = (e.target.body.scrollTop > 100);
  if (flag !== newFlag) {
    this.setState({showCompactStatusBar: newFlag});
    flag = newFlag;
  }
};

This will cause state change (and re-rendering) only when you pass the scrollTop threshold (100) from one direction or other. Otherwise we don't need to set state at all, thus avoiding render to be called.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download