phileras phileras - 1 year ago 68
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){
this.state = {
StatusBar: false

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

_handleOnScrollDocument(e) {
if ( > 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}/>

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 = ( > 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.