Redux FAQ:性能( Performance )
目录
- Redux 在性能和体系结构方面的“规模”如何?
- 不会为每个动作调用“所有减速器”会很慢吗?
- 我是否需要在减速器中克隆我的状态?是不是复制我的状态会变慢?
- 我如何减少商店更新事件的数量?
- “拥有一棵树”会导致内存问题吗?将调度许多行动占用内存?
性能
Redux 在性能和体系结构方面的“规模”如何?
尽管对此没有单一的明确答案,但大多数情况下,这两者都不应成为问题。
Redux 所做的工作通常包括以下几个方面:在中间件和简化器中处理操作(包括用于不可变更新的对象复制),在调度操作之后通知订户,以及根据状态更改更新UI组件。尽管在充分复杂的情况下,每种方法都 可能 成为性能问题,但 Redux 的实施方式并没有什么本质上的缓慢或低效。事实上,React Redux 尤其经过了大量优化,可以减少不必要的重新渲染,React-Redux v5相对于早期版本显示出明显的改进。
与其他库相比,Redux 可能没有那么高效。为了在 React 应用程序中获得最大的渲染性能,应该将状态存储为规范化的形状,许多单独的组件应该连接到商店而不是几个,并且连接列表组件应该将项目ID传递到其连接的子项列表项(允许列出项目以通过 ID 查找他们自己的数据)。这最大限度地减少了要完成的渲染总量。记忆选择器功能的使用也是重要的性能考虑因素。
至于架构,轶事证据表明,Redux 适用于不同的项目和团队规模。Redux 目前由数百家公司和数千名开发人员使用,每月有数十万次来自 NPM 的安装。一名开发人员报告
对于规模,我们有〜500个动作类型,〜400个减速器案例,〜150个组件,5个中间件,〜200个动作,〜2300个测试
更多信息
文档
- Recipes: Structuring Reducers - Normalizing State Shape(构造减速器 - 规范化状态形状)
文档
- How to Scale React Applications (accompanying talk: Scaling React Applications )(如何扩展React应用程序(随附讨论:缩放React应用程序))
- High-Performance Redux( 高性能Redux )
- Improving React and Redux Perf with Reselect( 重新选择改进React和Redux Perf )
- Encapsulating the Redux State Tree( 封装Redux状态树 )
- React/Redux Links: Performance - Redux( React/Redux链接:性能 - Redux )
讨论
- #310: Who uses Redux?( 谁使用Redux? )
- React Redux #269: Connect could be used with a custom subscribe method( Connect可以与自定义订阅方法一起使用 )
- React Redux #416: Rewrite connect for better performance and extensibility( 重写连接以获得更好的性能和可扩展性 )
- Redux vs MobX TodoMVC Benchmark: #1( Redux与MobX TodoMVC Benchmark:#1 )
- Reddit: What's the best place to keep the initial state?( 什么是保持初始状态的最佳地点? )
- Reddit: Help designing Redux state for a single page app( 帮助设计单个页面应用程序的Redux状态 )
- Reddit: Redux performance issues with a large state object?( 大型状态对象的Redux性能问题? )
- Reddit: React/Redux for Ultra Large Scale apps( React/Redux适用于超大型应用程序 )
- Twitter: Redux scaling( Twitter:Redux缩放 )
- Twitter: Redux vs MobX benchmark graph - Redux state shape matters( Twitter:Redux vs MobX 基准图 - Redux 状态形状很重要 )
- Stack Overflow: How to optimize small updates to props of nested components?( 堆栈溢出:如何优化嵌套组件的道具的小更新? )
- Chat log: React/Redux perf - updating a 10K-item Todo list( 聊天记录:React/Redux perf - 更新10K条目待办事项列表 )
- Chat log: React/Redux perf - single connection vs many connections( 聊天记录:React/Redux perf - 单连接与多个连接 )
不会为每个动作调用“所有减速器”会很慢吗?
重要的是要注意 Redux 商店真的只有一个 Reducer 功能。商店将当前状态和已分派的操作传递给该减速器功能,并让减速器适当地处理事情。
显然,试图处理单个函数中的每一个可能的动作并不能很好地扩展,仅仅是在函数大小和可读性方面,所以将实际工作分割成可以由顶级减速器调用的单独函数是有意义的。特别是,常见的建议模式是具有一个单独的子简化器函数,负责管理特定密钥的特定状态片更新。该
combineReducers()
随终极版是众多可能的方式来实现这一目标之一。同时强烈建议您保持商店状态尽可能平坦和规范。但最终,您负责以任何您想要的方式组织您的减速器逻辑。
但是,即使您碰巧有许多不同的减速机功能组合在一起,并且即使在深度嵌套状态下,减速机速度也不会成为问题。JavaScript 引擎每秒能够运行大量的函数调用,并且大多数 reducers 可能只是使用
switch
语句并默认返回现有状态以响应大多数操作。
如果您确实担心 Reducer 性能,可以使用诸如 redux-ignore 或 reduxr-scoped-reducer 之 类的实用程序来确保只有特定的 reducer 监听特定的操作。您也可以使用 redux-log-slow-redurs 来执行一些性能基准测试。
更多信息
讨论
- #912: Proposal: action filter utility( 建议:操作过滤器实用程序 )
- #1303: Redux Performance with Large Store and frequent updates( 大型商店和经常更新的Redux性能 )
- Stack Overflow: State in Redux app has the name of the reducer( 堆栈溢出:Redux 应用程序中的状态具有 reducer 的名称 )
- Stack Overflow: How does Redux deal with deeply nested models?( 堆栈溢出:Redux 如何处理深度嵌套模型? )
我是否需要在减速器中克隆我的状态?是不是复制我的状态会变慢?
不断更新状态通常意味着制作浅拷贝,而不是深拷贝。浅拷贝比深拷贝要快得多,因为需要拷贝更少的对象和字段,并且有效地归结为移动一些指针。
但是,您 确实 需要为受影响的每个嵌套级别创建一个复制和更新的对象。虽然这不应该特别昂贵,但如果可能的话,为什么你应该保持你的状态正常化和浅层化是另一个很好的理由。
常见的 Redux 误解:您需要深入克隆状态。现实:如果里面的东西没有改变,请保持它的参考相同!
更多信息
文档
- Recipes: Structuring Reducers - Prerequisite Concepts(构建Reducers - 先决条件的概念)
- Recipes: Structuring Reducers - Immutable Update Patterns(构建Reducers - 不变的更新模式)
讨论