【问题标题】:How to reduce renders using redux + normalizr如何使用 redux + normalizr 减少渲染
【发布时间】:2016-07-23 08:31:15
【问题描述】:

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

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

【问题讨论】:

  • 通常,React Shadow DOM 只更新真正改变的部分,即使所有 render() 方法都被调用以计算它。它应该保持相当快。你有任何性能问题吗?
  • 不管怎样,你可以看看shouldComponentUpdate生命周期方法来减少渲染计算的次数。
  • reselect 在某些情况下会为您提供帮助。

标签: performance reactjs redux react-redux normalizr


【解决方案1】:

您可以采取多种措施来最大程度地减少应用中的渲染次数,并加快更新速度。 让我们从 Redux 商店到 React 组件来看看它们。

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

  • 在您的容器中,即在您将 redux 状态作为道具注入的顶级组件中,仅询问您需要的状态切片,并使用 pure @987654322 @(我假设你正在使用 react-redux)以确保只有在 mapStateToProps 函数返回的状态切片发生更改时才会重新渲染容器。

  • 如果您需要计算派生数据,也就是说,如果您在容器中注入从各种状态切片计算的数据,请使用记忆函数来确保不会再次触发计算:输入不会改变,并保持对象与前一个调用返回的值相等。 Reselect 是一个非常好的库。

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

就 Normalizr 而言,没有什么更具体的事情要做。

【讨论】:

  • 为了帮助你决定在哪里进行优化,Dan Abramov 刚刚在 Twitter (twitter.com/dan_abramov/status/719723513016426496) 上说:“组件分离可以比手动 shouldComponentUpdate() 产生更大的影响”,因为“connect()在大多数情况下,React Redux 已经处理了 shouldComponentUpdate() 。专注于找到最佳的组件分离”。
  • @pierrepinard_2 非常感谢您的提醒!我已经编辑了答案以包含该评论
  • 关于第一项。能否提供一个 immutable + redux store 的例子?
  • @rat 好吧,假设你有一个 people reducer,其结构如下:{1: {name: 'John', status: 'admin'}, {2: {name: 'Jack', status: 'user'}},你可以让它成为不可变映射的不可变映射。像这样更新一个人:return state.setIn([1, 'status'], 'user') 将为people 返回一个新对象,为people.get(1) 返回一个新对象,但与之前people.get(2) 的对象相同
  • @VonD 谢谢。非常有帮助。我们在连接中运行这个逻辑(映射逻辑)。它似乎没有按预期工作。我有点担心在 redux 商店中使用它,因为它的实际派生数据不是一个状态。
【解决方案2】:

如果在某些情况下(应该很少见)你检测到与 React 的组件渲染周期直接相关的性能问题,那么你应该在涉及的组件中实现 shouldComponentUpdate() 方法(详情可以在 React 的文档here 中找到。

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
}

【讨论】:

猜你喜欢
  • 2016-11-03
  • 2011-06-04
  • 2010-10-27
  • 1970-01-01
  • 2021-02-18
  • 2021-11-19
  • 2012-07-28
  • 2021-07-06
  • 1970-01-01
相关资源
最近更新 更多