Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scroll lagging/slow performance #12

Closed
yarnball opened this issue Jun 15, 2017 · 5 comments
Closed

Scroll lagging/slow performance #12

yarnball opened this issue Jun 15, 2017 · 5 comments

Comments

@yarnball
Copy link

yarnball commented Jun 15, 2017

Hi,

This looks like a great little add on (only 3kb's!).

I'm having some difficultly implementing. I tried following your example, but had no success. T

I had some success. But performance isn't great. The scroll is laggy. I've probably implemented it wrong.

See here https://codesandbox.io/s/vo1xjpxrL

Here's the code:

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      demoData: x.demoData,
    };
  }
  render() {
    return (
        <VirtualList
    width='100%'
    height={800}
    itemCount={this.state.demoData.length}
    itemSize={50}
    renderItem={({index, style}) =>
      <div style={style} key={index}> 
{this.state.demoData.map(e => {
          return <Result e={e}/>;
        })[index]}
      </div>
    }
  />

    );
  }
}

class Result extends React.Component {
  render() {
    const { e, remove } = this.props;

    return (
      <div key={e.id}>
        {e.name} {' '} {e.id}
      </div>
    );
  }
}

Cheers,

@yarnball yarnball changed the title Example implementation- unable to see list Scroll lagging/slow performance Jun 15, 2017
@clauderic
Copy link
Owner

Right off the bat, your renderItem prop should be a class method, otherwise a new function gets re-created every single time render() is called, which in turn causes VirtualList to re-render, since it's props change when that happens.

Depending on how complex your rows are though, it's possible this is just a limitation with React. I see you're mapping multiple results per row, so depending on how many results you're mapping, this could be a source of performance issues.

You can also try lowering the overscanCount prop to reduce the number of rows that are rendered on screen.

@clauderic
Copy link
Owner

Ah, you were mapping through your entire dataset for every single row, instead of just accessing the right dataset for the row being rendered. Take a look at: https://codesandbox.io/s/1wqGN4WgG

@yarnball
Copy link
Author

yarnball commented Jul 3, 2017

Thank you- I see it no longer uses the .map. I followed your example, but the performance is terrible (unusable).

I have a feeling it is because I'm using functions inside renderItem. However, I do not know how to arrange the code to work otherwise.

How would I arrange renderItem to perform better?

Here is my attempt before putting const's into renderItem link

Here is my attempt as per below link

class App extends React.Component {
  ...
  renderItem = ({index, style}) => {
    const { selectedFilters, searchQuery, movies } = this.state;
    const moviesToHide = filterMovies( movies, searchQuery.split(' '), );

    const moviesNamesToHide = new Set(moviesToHide.map(m => m.name));
    const genresToShow = this.uniqueGenres1(moviesToHide);
    const genreNamesToShow = new Set(genresToShow.map(g => g.name));
    const allGenres = this.uniqueGenres1(movies);
    
    return (  
      <div style={style} key={index}> 
        {movies.map(e => {
          const isActive = moviesNamesToHide.has(e.name);
          return <Result key={e.id} result={e} isActive={isActive} />;
        })}
      </div>
    );
  }
  render() {
    ...
    return (
    ...
        <VirtualList
          width='100%'
          height={800}
          itemCount={this.state.movies.length}
          itemSize={50}
          renderItem={this.renderItem}
        />
    );
  }
}

@yarnball
Copy link
Author

yarnball commented Jul 12, 2017

How would I go about integrating with react motion? I might open a new issue for this.

 renderItem = ({ index, style }) => {
    return (
      <div style={style} key={index}>
        <TransitionMotion
          willLeave={this.willLeave}
          styles={this.props.res.map(item => ({
            key: item.id,
            style: { width: 20, height: 20 },
          }))}
        >
          {interpolatedStyles =>
           
            <div>
              {interpolatedStyles.map(config => {
                return (
                  <VirtResList
                    key={config.key}
                    style={{ ...config.style, border: '1px solid' }}
                    e={this.props.res[index]}
                  />
                );
              })}
            </div>}
        </TransitionMotion>
      </div>
    );
  };

As for my previous post, took a while to figure out- but got it working nicely.
https://codesandbox.io/s/kR3L5Oqnv

import React from 'react';
import { render } from 'react-dom';
import { x } from './data';
import Fuse from 'fuse.js';
import VirtualList from 'react-tiny-virtual-list';
import { TransitionMotion, spring } from 'react-motion';

class App extends React.Component {
  state = {
    demoData: x.demoData,
    search: '',
  };
  render() {
    const { demoData, search } = this.state;
    const options = { keys: ['name'],};
    const fuse = new Fuse(demoData, options);
    const listResult = search.length > 0 ? fuse.search(search) : demoData;
    return (
      <span>
        <input onChange={e => this.setState({ search: e.target.value })} />
        <VirtualList
          width="100%"
          height={1000}
          itemCount={listResult.length}
          itemSize={40}
          renderItem={({ index, style }) =>
            <div key={index} style={style}>
              <VirtList x={listResult[index]} />
            </div>}
        />
      </span>
    );
  }
}

class VirtList extends React.Component {
  render() {
    const { x } = this.props;

    return (
      <li>
        {x.name} {x.id}
      </li>
    );
  }
}

render(<App />, document.getElementById('root'));

@Odin-Taif
Copy link

Odin-Taif commented May 26, 2022

Check if you have

 html{
  scroll-behavior: smooth;
}

in your index.css or somewhere if so then delete it because, it causes some issues with react-scrolling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants