代码之家  ›  专栏  ›  技术社区  ›  meds

在React虚拟化中异步加载组件?

  •  0
  • meds  · 技术社区  · 6 年前

    我在组件中实现了一个反应虚拟化的砖石网格,如下所示:

    const MasonrySubmissionRender = (media: InputProps) => {
    
        function cellRenderer({ index, key, parent, style }: MasonryCellProps) {
            //const size = (media.submissionsWithSizes && media.submissionsWithSizes.length > index) ? media.submissionsWithSizes[index].size : undefined
            //const height = size ? (columnWidth * (size.height / size.width)) : defaultHeight;
            function getCard(index: number, extraProps: any) {
                var Comp = media.cardElement ? media.cardElement : SubmissionCard
    
                return <Comp submission={media.media[index]} {...media.customCardProps} />
            }
    
    
            return (
                <div>
                    <CellMeasurer
                        cache={cache}
                        index={index}
                        key={key}
                        parent={parent}>
                        <div style={style}>
                            {getCard(index, media.customCardProps)}
                        </div>
                    </CellMeasurer>
                </div>
            );
        }
    
        return (
            <Masonry
                overscanByPixels={1000}
                autoHeight={false}
                cellCount={media.media.length}
                cellMeasurerCache={cache}
                cellPositioner={cellPositioner}
                cellRenderer={cellRenderer}
                style={{ backgroundColor: 'red' }}
                height={900}
                width={900}
            />
        );
    };
    

    它呈现一个相当复杂的组件列表,其中包含一系列芯片、CSS动画等。

    因此,即使使用React虚拟化,渲染速度也非常慢。

    我想实现一个类似imgur.com的系统,在该系统中,组件本身不需要立即加载,只显示轮廓,而我可以让组件准备在后台渲染。

    我知道有一种方法可以在滚动时交换组件,但是他隐藏了所有组件,包括已经渲染的组件。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Ori Drori    6 年前

    masonry's cell render isScrolling

    if (isScrolling) return ( 
      <div>placeholder</div>
    );
    

    cellRenderer getCard media

    function getCard(media: InputProps, index: number) {
      var Comp = media.cardElement ? media.cardElement : SubmissionCard
    
      return <Comp submission = {
          media.media[index]
        } { ...media.customCardProps }
      />
    }
    
    class MasonrySubmissionRender extends React.Component {
    
      cellRenderer = ({
        index,
        key,
        parent,
        style,
        isScrolling
      }: MasonryCellProps) => {
        if (isScrolling) return ( 
          <div>placeholder</div>
        );
    
        return (
          <div>
              <CellMeasurer
                  cache={cache}
                  index={index}
                  key={key}
                  parent={parent}>
                  <div style={style}>
                      {getCard(media, index)}
                  </div>
              </CellMeasurer>
          </div>
        );
      }
    
      render() {   
        return (
          <Masonry
            overscanByPixels={1000}
            autoHeight={false}
            cellCount={media.media.length}
            cellMeasurerCache={cache}
            cellPositioner={cellPositioner}
            cellRenderer={this.cellRenderer}
            style={{ backgroundColor: 'red' }}
            height={900}
            width={900}
          />
        );
      }
    }