harsh atal
harsh atal

Reputation: 409

React application slow performance

I am trying to make a application in react for rendering a tree like structure which can be expanded and collapsed on user input, although i have managed to get the app working as I want but the performance is quite slow. I am not sure if this is because of the nature of the application, the react component or my ignorance of the framework.

I have done a chrome profiling and here are the screenshots:

Summary

Bottom Up

Call Tree

Please if you can help me understand through this images what is the bottleneck and if/how it can be solved.

Source :

https://github.com/harsh-a1/react-skeleton/tree/tree

Component :

export function TreeComponent(props){

var instance = Object.create(React.Component.prototype)

var state = {
    previousSelected :{},
    onSelectCallback : props.onSelectCallback
}
instance.props = props;   
var toggle = function(){
    instance.setState(state.data)
}
instance.updateState = function(){
    instance.setState(Object.assign({},state))

}

if (!props.data){
    init(function(ous){
        state.data = ous;
        instance.setState(state)

    });
}
instance.render = function(){
    if (!state.data){return <div key = "dummy"></div>}

    return <ul key={"ul_"+state.data.id}>
        <Tree data={state.data} updateState={instance.updateState} state={state } />
        </ul>
}


return instance;


function Tree(props){
    var instance = Object.create(React.PureComponent.prototype)

    instance.render = function(){
        if (!props.data.children || props.data.children.length == 0){
            return (
                    <li key={"li_"+props.data.id}>
                    <LeafNode data={props.data} updateState = {props.updateState} state={props.state}  />                
                    </li>
            )
        }

        return  (            
                <li key={"li_"+props.data.id}><LeafNode data={props.data} updateState = {props.updateState} state={props.state} />
                <ul key = {"ul_"+props.data.id} style={props.data.showChildren?{"display":"inline"}:{"display":"none"}}>
                {
                    props.data.children.map(function(child){
                        return <Tree data={child} key={"tree_"+child.id} updateState = {props.updateState} state={props.state}  />
                    })                
                }
            </ul></li>
        )
    }
    return instance;
    function LeafNode(props){
        var instance = Object.create(React.PureComponent.prototype)
        instance.props = props;   

    /*    instance.shouldComponentUpdate = function(nextProps) {
            return (nextProps.data.showChildren !== this.props.data.showChildren);
        }
    */
        instance.componentDidMount= function(){
              console.log("yes")
        }

        instance.toggle = function(){

            props.data.showChildren = !props.data.showChildren;
            props.updateState();
        }

        instance.selected = function(){
            props.state.previousSelected.selected = false;
            props.data.selected = !props.data.selected;                
            props.state.previousSelected = props.data;
            props.updateState();
            props.state.onSelectCallback(Object.assign({},props.data));

        }

        instance.render = function(){
            var toggleImg = "";

            if ( props.data.children.length!=0){
                toggleImg = props.data.showChildren  ?expandIMG:collapseIMG; 
            }            
            return (
                    <div key={"div_"+props.data.id} >
                    <span key={"span_"+props.data.id} className="toggle"  >
                    <img key={"img_"+props.data.id} width="12" height="12" src={toggleImg} onClick={instance.toggle} />
                    </span>
                    <a key={"a_"+props.data.id} onClick = {instance.selected} style={props.data.selected? {color:"yellow"}:{color:"black"}}  >{props.data.name}</a>
                    </div>
            )
        }
        return instance        
    }   
}
}

Thanks

harsh

Upvotes: 0

Views: 5381

Answers (3)

hampusohlsson
hampusohlsson

Reputation: 10219

Here is an example with 1M+ nodes and good performance. The trick is to use local state and not render the hidden elements.

https://codesandbox.io/s/z6jr6zww4l

Upvotes: 1

harsh atal
harsh atal

Reputation: 409

Turns out The issue was that I was using the "development" build to check it....i switched to a production library and now it is running not to bad...still not as good as direct DOM but pretty close...although don't know how much it can scale...

Upvotes: 0

Alex
Alex

Reputation: 2174

Have a look at best practices how to create components and component lifecycle at React website. It is a good idea to follow them so it would be easier to identify problems later.

It is also worth looking at react-virtualized components. There are a bunch of components that could be reused including list, grid, tree etc. Also look at their implementation since it is opensource.

Their virtual list component resolved my issue with rendering 500+ items.

Upvotes: 1

Related Questions