React extremely slow when iterating through JSON

时间:2022-03-20 20:20:53

So, Im trying to fetch an JSON API with fetch() and iterate through it and render it in Reactjs. It does actually work pretty well with small json lists up to 100 items. But when I try the same thing with a json list of 900 items and upwards, it takes quite a while and the entire site isnt responsive anymore and gets pretty slow.

所以,我试图用fetch()获取一个JSON API并迭代它并在Reactjs中渲染它。它实际上可以很好地使用最多100个项目的小json列表。但是当我用900个项目及以上的json列表尝试相同的事情时,它需要相当长的一段时间,整个站点不再响应并且变得非常慢。

So what am I doing wrong here and what can I fix to make the site faster?

那么我在这里做错了什么以及我可以修复哪些方法来加快网站速度呢?

API.js

import _ from 'lodash/array';    
const baseURL = 'https://url.com/api/v1';
class API {
  static getLibrary(user, callback) {
    fetch(`${baseURL}/users/${user}/library`, {
      method: 'get',
      headers: { 'Content-type': 'application/json' },
    })
    .then((response) => {
      response.json().then((data) => {
        const titles = [];
        const status = [];
        const covers = [];
        const url = [];
        const rating = [];
        const episodesWatched = [];
        const episodesMax = [];
        for (const item in data) {
          titles.push(data[item].library.title);
          status.push(data[item].status);
          covers.push(data[item].library.cover_image);
          url.push(data[item].library.url);
          rating.push(data[item].rating);
          episodesWatched.push(data[item].episodes_watched);
          episodesMax.push(data[item].library.episode_count);
        }
        const library = _.zip(
          titles,
          covers,
          url,
          rating,
          episodesWatched,
          episodesMax
        );
        callback(library);
      });
    });
  }
}
export default API;

Index.jsx:

import React from 'react';
import API from '../modules/api';
import { Grid, Row, Col } from 'react-flexgrid';
import Blazy from 'blazy';
import _ from 'lodash/collection';

class Library extends React.Component {
  constructor() {
    super();
    this.state = {
      library: undefined,
    };
  }

  componentDidMount() {
    API.getLibrary(this.props.params.user, (list) => {
      this.setState({
        library: _.sortBy(list, 0),
      });
    });
  }
  render() {
    var bLazy = new Blazy();
    if (this.state.library) {
      return (
        <div className="content">
          <Grid>
            <Row>
            {this.state.library.map(function(entry, index) {
              return (
                <Col key={index} xs={6} md={2}>
                  <Card>
                    <CardTitle>{entry[0]}</CardTitle>
                  </Card>
                </Col>
                );
            })}
            </Row>
          </Grid>
        </div>
      );
    }
    return (
      <div>
        Loading
      </div>
    );
  }
}

export default Library;

2 个解决方案

#1


2  

It's not clear from the code provided where the issue is. Possible culprits:

从问题所在的代码处不清楚。可能的罪魁祸首:

  • Your post-processing logic (_.zip, _.sortBy) is slow, and causes the UI to lock. I'd start by timing these operations and seeing whether they represent a significant bottleneck.

    您的后处理逻辑(_.zip,_.sortBy)很慢,导致UI锁定。我首先考虑这些操作的时间安排,看看它们是否代表了一个重要的瓶颈。

  • You end up with a large number of DOM elements, and this causes the page to appear sluggish. There are various ways to fix this, but pagination or infinite scroll are good top-of-mind approaches. You might try FixedDataTable for a good lazy-rendering implementation for large data tables.

    最终会出现大量DOM元素,这会导致页面显得迟缓。有各种方法来解决这个问题,但是分页或无限滚动是最好的头脑方法。您可以尝试使用FixedDataTable为大型数据表提供良好的延迟呈现实现。

#2


1  

Rendering 900 items even directly in the DOM with element.innerHTML can be slow. So you might want to a use a list implementation like this one https://github.com/seatgeek/react-infinite which would load things into the DOM as you scroll.

使用element.innerHTML甚至直接在DOM中渲染900个项目可能会很慢。因此,您可能希望使用像这样的列表实现https://github.com/seatgeek/react-infinite,它会在您滚动时将内容加载到DOM中。

Also when you assign key={index} it is a good practice to use unique keys, otherwise React would be confused in case you would reorder or change your list at some point

此外,当您指定key = {index}时,最好使用唯一键,否则React会因为您在某个时候重新排序或更改列表而感到困惑

#1


2  

It's not clear from the code provided where the issue is. Possible culprits:

从问题所在的代码处不清楚。可能的罪魁祸首:

  • Your post-processing logic (_.zip, _.sortBy) is slow, and causes the UI to lock. I'd start by timing these operations and seeing whether they represent a significant bottleneck.

    您的后处理逻辑(_.zip,_.sortBy)很慢,导致UI锁定。我首先考虑这些操作的时间安排,看看它们是否代表了一个重要的瓶颈。

  • You end up with a large number of DOM elements, and this causes the page to appear sluggish. There are various ways to fix this, but pagination or infinite scroll are good top-of-mind approaches. You might try FixedDataTable for a good lazy-rendering implementation for large data tables.

    最终会出现大量DOM元素,这会导致页面显得迟缓。有各种方法来解决这个问题,但是分页或无限滚动是最好的头脑方法。您可以尝试使用FixedDataTable为大型数据表提供良好的延迟呈现实现。

#2


1  

Rendering 900 items even directly in the DOM with element.innerHTML can be slow. So you might want to a use a list implementation like this one https://github.com/seatgeek/react-infinite which would load things into the DOM as you scroll.

使用element.innerHTML甚至直接在DOM中渲染900个项目可能会很慢。因此,您可能希望使用像这样的列表实现https://github.com/seatgeek/react-infinite,它会在您滚动时将内容加载到DOM中。

Also when you assign key={index} it is a good practice to use unique keys, otherwise React would be confused in case you would reorder or change your list at some point

此外,当您指定key = {index}时,最好使用唯一键,否则React会因为您在某个时候重新排序或更改列表而感到困惑