Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如何在React中进行组件池?_Performance_Reactjs_Components - Fatal编程技术网

Performance 如何在React中进行组件池?

Performance 如何在React中进行组件池?,performance,reactjs,components,Performance,Reactjs,Components,在资源有限的设备中,通常的做法是通过组件池来利用性能。例如,有一个无休止的滚动列表。由于视口中始终显示大约10个组件,所以池中只能有20个组件实例。当用户向上或向下滚动时,顶部或底部的组件切换到另一侧并填充新数据。这样,用户感觉列表很长,但只需要20个组件实例 使用jQuery和命令式编程,很容易实现这种组件池技巧。然而,在React世界中,UI是声明性的 const List = ({listData}) => { return <ul> {listData.ma

在资源有限的设备中,通常的做法是通过组件池来利用性能。例如,有一个无休止的滚动列表。由于视口中始终显示大约10个组件,所以池中只能有20个组件实例。当用户向上或向下滚动时,顶部或底部的组件切换到另一侧并填充新数据。这样,用户感觉列表很长,但只需要20个组件实例

使用jQuery和命令式编程,很容易实现这种组件池技巧。然而,在React世界中,UI是声明性的

const List = ({listData}) => {
  return <ul>
    {listData.map(item => <li>{item}</li>);
  </ul>;
}
const List=({listData})=>{
返回
    {listData.map(item=>
  • {item}
  • );
; }
代码只是声明有一个要显示的项目列表。我们的代码没有进行组件池的控制;我相信React本身将创建DOM池

那么,如何实现组件池以获得更好的性能呢?

该库是在React应用程序中使用的虚拟列表的直接实现。它经过了大量优化,我认为它使用了大量的引用和DOM交互来完成它需要做的事

也就是说,虽然我从来没有在React(或其他地方)中实际尝试过实现虚拟列表或组件池,但我可以想象一些基本概念可能是正确的

对于本例,我们有一个包含1000个项目的列表,但只想显示20个项目。首先,您需要在
render
中执行所有正确的分页和窗口设置。假设用户向下滚动了30个项目,所以我们想显示30-50个项目。通常,在React中呈现项目列表时,您需要根据ID为每个项目分配键从数据中,或作为回退,数组索引

通常情况下,使用数组索引作为键是不好的,因为更改内容会让React认为东西已经被转移了。不像您通常希望的那样让组件装载和卸载,组件将保持装载状态,但突然收到一组不同的道具。但是,在这种情况下,这似乎是您想要的行为。

因此,完全未经测试和假设,但似是而非的示例代码:

render() {
    const {items} = this.props;
    const {displaySize, startIndex} = this.state;

    const itemsToDisplay = items.slice(startIndex, startIndex + displaySize + 1);

    const renderedItems = itemsToDisplay.map( (item, index) => {
        return <ListItem item={item} key={index} />
    });

    return (
        <div>
            {renderedItems}
        </div>
    );
}
render(){
const{items}=this.props;
const{displaySize,startIndex}=this.state;
const itemsToDisplay=items.slice(startIndex,startIndex+displaySize+1);
const renderItems=itemsToDisplay.map((项,索引)=>{
返回
});
返回(
{renderItems}
);
}

谢谢你的提醒,Mark!关于这个例子,需要指出的一点是,它会导致不必要的DOM更新,因为每次更改开始索引时,所有元素都会更新。每个元素的键都会移动。你可以尝试旋转键(例如
(startIndex+index)%poolSize
)只要池大小稳定。对于RV,我发现只将键设置为
startIndex+index
更好,但YMMV.Bah,旋转键应该是
(startIndex+index)%(displaySize+1)