Search code examples
javascriptreduxreact-reduxreselect

Filtering performance with large lists


I have a list of ~5000 elements and I would like to filter it by searchPhrase which is given by user. Usually user types first letter of filtering phrase, then second and then third. For example user types 'a', then 'ab', then 'abc'.

I'm trying to use reactjs/reselect library to improve filtering performance. I have used this lib as in Example on readme: Example I have changed this method:

export const getVisibleTodos = createSelector(
  [ getVisibilityFilter, getTodos ],
  (visibilityFilter, todos) => {
    switch (visibilityFilter) {
      case 'SHOW_ALL':
        return todos
      case 'SHOW_COMPLETED':
        return todos.filter(t => t.completed)
      case 'SHOW_ACTIVE':
        return todos.filter(t => !t.completed)
    }
  }
)

to that implementation:

export const getVisibleTodos = createSelector(
    [getSearchPhrase, getTodos],
    (searchPhrase, todos) => {
        return todos.filter((x) => {
            return x.firstName.indexOf(searchPhrase) >= 0;
        });
    }
)

I noticed that each time when user types next letter todos.length property is the same. Shouldn't todos.length be shorter when searchPhrase is longer? I think that performance without reactjs/reselect is the same.

Is that possibility to filter shorter todos list when previous searchPhrase is substring of actual searchPhrase?


Solution

  • That's not how reselect improves performance: the actual filtering of the todos takes exactly the same time with or without reselect.

    What reselect does for you is to memoize the filtering: as long as getSearchPhrase and getTodos return the same value (as defined by === equality), calling getVisibleTodos multiple times does the filtering only once.

    This is important in a complex app, where you have many unrelated changes to redux state: without reselect any change to the state would result in all selectors being run again, even if that part of the state is unchanged.