Performance 如何使用redux+;标准化器

Performance 如何使用redux+;标准化器,performance,reactjs,redux,react-redux,normalizr,Performance,Reactjs,Redux,React Redux,Normalizr,我有一个使用React+Redux+normalizer的应用程序,我想知道当实体发生变化时减少渲染次数的最佳实践 如果我只更改实体中的一个实体,它将重新渲染所有组件,而不仅仅是需要该特定实体的组件如果在某些情况下(应该很少)您检测到与React的组件渲染周期直接相关的性能问题,然后,您应该在相关组件中实现shouldComponentUpdate()方法(详细信息可在React的文档中找到) shouldComponentUpdate()中的更改检测将特别容易,因为Redux强制您实现不可变状

我有一个使用React+Redux+normalizer的应用程序,我想知道当
实体发生变化时减少渲染次数的最佳实践

如果我只更改实体中的一个实体,它将重新渲染所有组件,而不仅仅是需要该特定实体的组件

如果在某些情况下(应该很少)您检测到与React的组件渲染周期直接相关的性能问题,然后,您应该在相关组件中实现shouldComponentUpdate()方法(详细信息可在React的文档中找到)

shouldComponentUpdate()中的更改检测将特别容易,因为Redux强制您实现不可变状态:

shouldComponentUpdate(nextProps, nextState) {

    return nextProps.dataObject !== this.props.dataObject;

    // true when dataObject has become a new object,
    // which happens if (and only if) its data has changed,
    // thanks to immutability
}

你可以做几件事来最小化应用程序中的渲染数量,并加快更新速度。 让我们从Redux应用商店到React组件来看看它们

  • 在Redux存储中,可以使用不可变的数据结构(例如,)。这将加快所有后续优化的速度,因为您可以通过只检查上一个/下一个状态片的相等性来比较更改,而不是递归地比较所有道具

  • 在容器中,也就是在顶级组件中,您将redux state作为道具注入其中,只请求所需的状态片,并使用
    (我假设您使用的是react redux)确保仅当
    mapstatetops
    函数返回的状态片已更改时,才会重新渲染容器

  • 如果需要计算派生数据,即如果将从各种状态片计算的数据注入容器中,请使用记忆函数确保在输入未更改时不会再次触发计算,并保持对象与上一次调用返回的值相等。这是一个很好的图书馆

  • 在哑组件中使用
    shouldComponentUpdate
    生命周期,以避免在传入的道具未更改时重新渲染。如果不想手动执行此操作,可以使用React检查所有道具,或者,如果需要更多控制,可以使用库中的
    pure
    函数。这个级别的一个好用例是呈现一个项目列表。如果项目组件实现了
    shouldComponentUpdate
    ,则只会重新呈现修改后的项目。但这不应该是一个解决所有问题的习惯:一个好的组件分离通常更可取,因为它只为那些需要它们的组件提供流道具


就normalizer而言,没有比这更具体的操作了。

通常,React Shadow DOM只更新真正更改的内容,即使调用所有
render()
方法来计算它。它应该保持相当快。您是否有任何评测性能问题?无论如何,您可以查看
shouldComponentUpdate
lifecycle方法以减少渲染计算的数量。在某些情况下会对你有所帮助。这条评论解释得稍微好一点-你能回答这条评论吗-?至少对我来说,如果你使用的是琐碎的数据,这条评论是有效的。当您使用派生数据(例如表单重新选择)时,上面的不等式将无法帮助您确定优化的位置,丹·阿布拉莫夫在Twitter()上说:“组件分离可能比手动应在任何地方进行组件更新()产生更大的差异”,因为“connect()在大多数情况下,React Redux已经负责shouldComponentUpdate()。专注于寻找最佳组件分离。“@pierrepinard_2非常感谢您的提醒!我对答案进行了编辑,以包含关于第一项的注释。你能提供一个immutable+redux store的例子吗?@rat好吧,让我们假设你有一个
还原器,它的结构如下:
{1:{name:'John',status:'admin'},{2:{name:'Jack',status:'user'}}
,你可以把它变成一个不可变映射的不可变映射。更新一个人,像这样:
return state.setIn([1,'status'],'user')
将为
人员
返回一个新对象,为
人员返回一个新对象。get(1)
但为
人员返回与以前相同的对象。get(2)
@von谢谢。非常有用。我们有这个逻辑(映射逻辑)在connect中运行。它似乎没有按预期工作。我有点担心在redux存储中使用它,因为它不是一个状态,而是它实际派生的数据。