Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extremely slow React list render

Tags:

reactjs

We are experiencing some frustrating issues with React. We have a form, consisting from a search form and a search result list. As seen below in the code. filter and content.

Whenever the user types in the search field, there is a debounce and a call to a rest service.

The result then populates the search result (content)

Even with as little as 15 items in the list, this is insanely slow. it takes about 300 ms per update. In production mode, there is no issue. only in dev mode. Also, removing propTypes makes it much faster but still slow.

We can see that the ContactSearchResultLayout is being rendered 3 times per keystroke, while it really just should care about the result of the rest call.

What are our best bets here? is the container component kind of pattern here wrong for our usecase, does it mean that if something in the SearchPageLayout props changes, the entire list will also be re-rendered?

We have a version that pretty much bypass React and just render item by item as they come in from the service call. Which is super fast, but on the other hand, much less maintainable.

Is there some idiomatic way to make this work with React?

<SearchPageLayout
  filter={
    <ContactSearchForm
      allTeams={allTeams}
      allAreasOfExp={allAreasOfExp}
      allResponsiblePeople={allResponsiblePeople}
      allTags={allTags}
      detailed={props.searchFormExpanded}
      onSearchFieldBlur={() => props.setSearchFormExpanded(false)}
      onSearchFieldFocus={() => props.setSearchFormExpanded(true)}
    />
  }
  content={
    <ContactSearchResultLayout       //<-- this rerenders too often
      items={items.map(item => (
        <ContactCard
          key={item.PersonId}
          areasOfExpertise={item.AreasOfExperise}
          cellPhone={item.CellPhone}
          city={item.City}

One reason for this as I see it, is that items is the result of a map operation and thus, causes a new array of components to be generated. But how do we bypass this?

Thoughts?

like image 272
Roger Johansson Avatar asked Dec 17 '25 13:12

Roger Johansson


1 Answers

Anonymous function will get rendered each time.

I'll create another method for creating the items:

getItems() {
    return (
       items.map(item => (
        <ContactCard
          key={item.PersonId}
          areasOfExpertise={item.AreasOfExperise}
          cellPhone={item.CellPhone}
          city={item.City}
          />
       )
    )
 }

<ContactSearchResultLayout       
  items={this.getItems()} 
   />

How to check if props change and if you should re-render the code:

you can use react "shouldComponentUpdate" https://reactjs.org/docs/react-component.html#shouldcomponentupdate

componentWillUpdate(nextProps, nextState) {
    //here you can compare your current state and props
    // with the next state and props
    // be sure to return boolean to decide to render or not
}
like image 157
Tzook Bar Noy Avatar answered Dec 20 '25 15:12

Tzook Bar Noy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!