- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Redux 中,对 store 的每次更改都会触发 notify
在所有连接的组件上。这使开发人员的工作变得非常简单,但是如果您有一个包含 N 个连接组件的应用程序,并且 N 非常大怎么办?
对存储的每次更改,即使与组件无关,仍会运行 shouldComponentUpdate
用一个简单的 ===
在 reselect
上测试商店的 ed 路径。这很快,对吧?当然,也许一次。但是 N 次,对于每一个变化?这种设计上的根本变化让我怀疑 Redux 的真正可扩展性。
作为进一步的优化,可以批量处理所有 notify
使用 _.debounce
调用.即便如此,有 N ===
测试每个存储更改和处理其他逻辑,例如 View 逻辑,似乎是达到目的的一种手段。
我正在开发一个拥有数百万用户的健康和健身社交移动网络混合应用程序,并且正在从 过渡Redux 的主干 .在这个应用程序中,用户会看到一个可滑动的界面,允许他们在不同的 View 堆栈之间导航,类似于 Snapchat,但每个堆栈都有无限深度。在最流行的 View 类型中,无限滚动条可以有效地处理提要项目(如帖子)的加载、渲染、附加和分离。对于参与的用户来说,滚动浏览数百或数千个帖子,然后输入一个用户的提要,然后是另一个用户的提要等的情况并不少见。即使进行大量优化,连接组件的数量也会变得非常大。
另一方面,Backbone 的设计允许每个 View 精确地听取影响它的模型,将 N 减少到一个常数。
我是否遗漏了什么,或者 Redux 对于大型应用程序是否存在根本性的缺陷?
最佳答案
恕我直言,这不是 Redux 固有的问题。
顺便说一句,与其尝试同时渲染 100k 个组件,您应该尝试使用像 react-infinite 这样的库来伪造它。或类似的东西,只呈现列表中可见(或接近)的项目。即使您成功渲染和更新 100k 列表,它仍然没有性能,并且需要大量内存。这里有一些 LinkedIn advices
此 anwser 将考虑您仍然尝试在 DOM 中呈现 100k 可更新项目,并且您不希望在每次更改时都调用 100k 监听器( store.subscribe()
)。
2所学校
在以功能方式开发 UI 应用程序时,您基本上有两种选择:
始终从顶部渲染
它运行良好,但涉及更多样板。这不完全是建议的 Redux 方式,但可以实现,有一些 drawbacks .请注意,即使您设法拥有一个 redux 连接,您仍然必须调用很多 shouldComponentUpdate
在很多地方。如果您有无限的 View 堆栈(如递归),则必须将所有中间 View 以及 shouldComponentUpdate
渲染为虚拟 dom。他们中的许多人将被召唤。因此,即使您只有一个连接,这也不是更有效。
如果你不打算使用 React 生命周期方法而只使用纯渲染函数,那么你可能应该考虑其他类似的选项,这些选项只会专注于该工作,例如 deku (可与 Redux 一起使用)
根据我自己的经验,使用 React 在较旧的移动设备(例如我的 Nexus4)上性能不够,尤其是当您将文本输入链接到原子状态时。
将数据连接到子组件
这是什么react-redux建议使用 connect
.因此,当状态发生变化并且它仅与更深层次的子级相关时,您只需渲染该子级,而不必每次都渲染顶级组件,例如上下文提供程序(redux/intl/custom...)或主应用程序布局。您还避免拨打 shouldComponentUpdate
在其他 child 身上,因为它已经融入了听众。调用大量非常快的监听器可能比每次渲染中间 react 组件更快,而且它还允许减少大量传递 Prop 的样板,因此对我而言,与 React 一起使用时它是有意义的。
另请注意,身份比较非常快,您可以在每次更改时轻松完成其中的很多工作。记住 Angular 的脏检查:有些人确实设法用它构建了真正的应用程序!身份比较要快得多。
了解您的问题
我不确定是否完全理解您的所有问题,但我知道您的 View 中有 10 万个项目,您想知道是否应该使用 connect
使用所有这些 100k 项,因为在每次更改时调用 100k 监听器似乎代价高昂。
这个问题似乎是使用 UI 进行函数式编程的本质所固有的:列表已更新,因此您必须重新渲染列表,但不幸的是,它是一个很长的列表,而且似乎效率低下......使用 Backbone,您可以破解只渲染 child 的东西。即使您使用 React 渲染该子项,您也会以命令式方式触发渲染,而不仅仅是声明“当列表更改时,重新渲染它”。
解决您的问题
显然,连接 100k 列表项看起来很方便,但由于调用了 100k react-redux 监听器,因此性能不佳,即使它们速度很快。
现在,如果您连接包含 100k 个项目的大列表而不是单独连接每个项目,您只需调用一个 react-redux 监听器,然后必须以有效的方式呈现该列表。
天真的解决方案
迭代 100k 个项目来渲染它们,导致 99999 个项目在 shouldComponentUpdate
中返回 false和一个重新渲染:
list.map(item => this.renderItem(item))
connect
+ 存储增强器
connect
React-Redux 的方法只是一个
Higher-Order Component (HOC) 将数据注入(inject)到被包装的组件中。为此,它注册了一个
store.subscribe(...)
每个连接组件的监听器。
connect
你可以建立自己的。
store.subscribeItem(itemId,listener)
dispatch
这样无论何时调度与项目相关的操作,您都可以调用该项目的注册监听器。
Item = connectItem(Item)
itemId
属性(property)。它可以使用 React 上下文中的 Redux 增强存储,然后注册其监听器:
store.subscribeItem(itemId,callback)
.源代码原
connect
可以作为基础灵感。
class MyItemComponent extends Component {
state = {
itemUpdated: undefined, // Will store the local
};
componentDidMount() {
this.unsubscribe = this.props.store.addDispatchListener(action => {
const isItemUpdate = action.type === "MY_ITEM_UPDATED" && action.payload.item.id === this.props.itemId;
if (isItemUpdate) {
this.setState({itemUpdated: action.payload.item})
}
})
}
componentWillUnmount() {
this.unsubscribe();
}
render() {
// Initially use the data provided by the parent, but once it's updated by some event, use the updated data
const item = this.state.itemUpdated || this.props.item;
return (
<div>
{...}
</div>
);
}
}
redux-dispatch-subscribe
性能可能不是很好,因为您仍然会创建 10 万个订阅。您宁愿构建自己的优化中间件,类似于
redux-dispatch-subscribe
使用类似
store.listenForItemChanges(itemId)
的 API ,将项目监听器存储为 map ,以便快速查找要运行的正确监听器...
shouldComponentUpdate
在 children 。
<span>
污染了 DOM。节点(
issue )。
shouldComponentUpdate
.在我的示例中,我每秒只更新第一项,您会注意到即使列表有 100k 项,它也只需要对
shouldComponentUpdate
进行 110 次调用。这是更容易接受的! :)
list.push(value)
很多时候似乎比调用
list.concat(values)
保留了更多的树结构。 .
Lists implement Deque, with efficient addition and removal from both the end (push, pop) and beginning (unshift, shift).
关于performance - 比如说 Backbone,React-Redux 应用程序真的可以扩展吗?即使重新选择。在移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34782249/
我正在开发日历中的事件功能,但我陷入了一件事。 这是我所做的:我有一个页面/界面,其中日 View 可见。用户可以滚动到下一天/前一天,并且同一 View 会重新加载特定日期的信息。所有这些事情都是动
我正在寻找解释这种(相当明智的)行为的 CSS 标准部分。也就是说,如果我编写属性 body { color: green; } 我希望(阅读文档,而不是根据经验)所有 body 的 child 都有
我的拟合函数是非凸的,因此损失函数有时会在改善之前恶化。鉴于此,我想使用提前停止,但只能在前 100 个或更多时期之后使用。到目前为止我有这个: # Early stopping ES = [Earl
我收到了将 DPX 文件编码为 MOV/MJPEG 而不是 MOV/H.264 的请求(如果您转换为 output.mov,则 ffmpeg 默认选择该文件)。这些是评论compositing渲染(运
在 Redux 中,对 store 的每次更改都会触发 notify在所有连接的组件上。这使开发人员的工作变得非常简单,但是如果您有一个包含 N 个连接组件的应用程序,并且 N 非常大怎么办? 对存储
查看图片以确保清晰度。 我有 5 个变量(A、B、C、D 和 E),每个变量的范围为 0-100。我需要所有这些变量的总和始终为 100,不能多也不能少。然而,按照目前的设置方式,如果我将变量 A 从
我正在编写一个应该使用cursesw/ncursesw的应用程序在各种不同的 Unix/Linux 平台上。 我如何知道发行版是否是从头开始安装的默认情况下包含这些库(或任何其他库)。(无需重新安装并
我在运行 compile test:compile it:compile经常并且...希望将击键次数减少到类似 *:compile 的数量。 .不过,它似乎不起作用。 $ sbt *:compile
现在我有一个小程序试图有效地将消息分成几部分,计算需要将字符单独附加到 OutputStream,通常是 BAOS,然后执行类似于 byte[] packed = packData(baos) 并根据
我有一个 JMenuItem 实例(比如说 TEMP)。我想知道添加了 TEMP 的 JMenu 的名称是什么。我该怎么做? 最佳答案 您可以尝试以下代码来获取给定 JMenuItem 的 JMenu
我是一名优秀的程序员,十分优秀!