React性能优化
当大家考虑在项目中使用 React 的时候,第一个问题往往是他们的应用的速度和响应是否能和非 React 版一样,每当状态改变的时候就重新渲染组件的整个子树,让大家怀疑这会不会对性能造成负面影响。React 用了一些黑科技来减少 UI 更新需要的花费较大的 DOM 操作。 使用 production 版本如果你在你的 React app 中进行性能测试或在寻找性能问题,一定要确定你在使用 minified production build。开发者版本包括额外的警告信息,这对你在开发你的 app 的时候很有用,但是因为要进行额外的处理,所以它也会比较慢。 避免更新 DOMReact 使用虚拟 DOM,它是在浏览器中的 DOM 子树的渲染描述,这个平行的描述让 React 避免创建和操作 DOM 节点,这些远比操作一个 JavaScript 对象慢。当一个组件的 props 或 state 改变,React 会构造一个新的虚拟 DOM 和旧的进行对比来决定真实 DOM 更新的必要性,只有在它们不相等的时候,React 才会使用尽量少的改动更新 DOM。 在此之上,React 提供了生命周期函数 shouldComponentUpdate: function(nextProps,nextState) { return true; } 一定要记住,React 会非常频繁的调用这个函数,所以要确保它的执行速度够快。 假如你有个带有多个对话的消息应用,如果只有一个对话发生改变,如果我们在 shouldComponentUpdate: function(nextProps,nextState) { // TODO: return whether or not current chat thread is // different to former one. } 因此,总的说,React 通过让用户使用 shouldComponentUpdate 实战这里有个组件的子树,每一个都指明了
在上面的示例中,因为 C2 的 C1 和 C3 的 注意 React 只需要对 C6 进行 DOM 转换,这是必须的。对于 C8,通过虚拟 DOM 的对比确定它是不需要的,C2 的子树和 C7,它们甚至不需要计算虚拟 DOM,因为 那么,我们怎么实现 React.createClass({ propTypes: { value: React.PropTypes.string.isRequired },render: function() { return <div>{this.props.value}</div>; } }); 我们可以简单的实现 shouldComponentUpdate: function(nextProps,nextState) { return this.props.value !== nextProps.value; } 非常好!处理这样简单结构的 props/state 很简单,我门甚至可以归纳出一个基于浅对比的实现,然后把它 Mixin 到组件中。实际上 React 已经提供了这样的实现: PureRenderMixin 但是如果你的组件的 props 或者 state 是可变的数据结构呢?比如说,组件接收的 prop 不是一个像 React.createClass({ propTypes: { value: React.PropTypes.object.isRequired },render: function() { return <div>{this.props.value.foo}</div>; } }); 前面的 // assume this.props.value is { foo: 'bar' } // assume nextProps.value is { foo: 'bar' },// but this reference is different to this.props.value this.props.value !== nextProps.value; // true 这个问题是当 prop 没有改变的时候 shouldComponentUpdate: function(nextProps,nextState) { return this.props.value.foo !== nextProps.value.foo; } 基本上,我们结束了使用深度对比来确保改变的正确跟踪,这个方法在性能上的花费是很大的,因为我们需要为每个 model 写不同的深度对比代码。就算这样,如果我们没有处理好对象引用,它甚至不能工作,比如说这个父组件: React.createClass({ getInitialState: function() { return { value: { foo: 'bar' } }; },onClick: function() { var value = this.state.value; value.foo += 'bar'; // ANTI-PATTERN! this.setState({ value: value }); },render: function() { return ( <div> <InnerComponent value={this.state.value} /> <a onClick={this.onClick}>Click me</a> </div> ); } }); 内部组件第一次渲染的时候,它会获取 这里的问题是因为父组件和内部组件共享同一个对象的引用,当对象在 因此,我们会丢失 prop 的改变,缩短重新渲染过程,UI 也不会从 Immutable-js 来救赎Immutable-js 是 Lee Byron 写的 JavaScript 集合类型的库,最近被 Facebook 开源,它通过结构共享提供不可变持久化集合类型。一起看下这些特性的含义:
不可变让跟踪改变非常简单;每次改变都是产生新的对象,所以我们仅需要对象的引用是否改变,比如这段简单的 JavaScript 代码: var x = { foo: "bar" }; var y = x; y.foo = "baz"; x === y; // true 尽管 var SomeRecord = Immutable.Record({ foo: null }); var x = new SomeRecord({ foo: 'bar' }); var y = x.set('foo','baz'); x === y; // false 这个例子中,因为改变 脏检测可以作为另外的可行的方式追踪改变,给 setters 一个标示。这个方法的问题是,它强制你使用 setters,而且要写很多额外的代码,影响你的类。或者你可以在改变之前深拷贝对象,然后进行深对比来确定是不是发生了改变。这个方法的问题是,深拷贝和深对比都是很花性能的操作。 因此,不可变数据结构给你提供了一个高效、简洁的方式来跟踪对象的改变,而跟踪改变是实现 Immutable-js 和 Flux如果你在使用 Flux,你应该开始使用 immutable-js 写你的 stores,看一下 full API。 让我们看一个可行的方式,使用不可变数据结构来给消息示例创建数据结构。首先我们要给每个要建模的实体定义一个 var User = Immutable.Record({ id: undefined,name: undefined,email: undefined }); var Message = Immutable.Record({ timestamp: new Date(),sender: undefined,text: '' });
消息的 store 可以使用两个 list 来跟踪 users 和 messages: this.users = Immutable.List(); this.messages = Immutable.List(); 实现函数处理每个 payload 类型应该是比较简单的,比如,当 store 看到一个代表新消息的 payload 时,我们就创建一个新的 record,并放入消息列表: this.messages = this.messages.push(new Message({ timestamp: payload.timestamp,sender: payload.sender,text: payload.text }); 注意:因为数据结构不可变,我们需要把 push 方法的结果赋给 在 React 里,如果我们也使用 immutable-js 数据结构来保存组件的 state,我门可以把 这篇文章是翻译React官方文档 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ruby-on-rails – 在RSpec中使用Thread.new测试并发性
- react-native启动服务
- ruby-on-rails – 如何编写rails路由来映射带有主要版本和次
- 未能加载文件或程序集或它的某一个依赖项
- ruby-on-rails – 查询上的Mongoid无限循环
- H5和PC实现点击复制当前文字的功能,兼容ios,安卓
- 存储过程中“ 警告: 聚合或其他 SET 操作消除了 Null 值”
- c# – 如何通过按DeleteKey删除DataGridView行?
- regex – 生成正则表达式的所有可能匹配项
- c# – 如何从HttpPost Create操作方法中了解所选复选框?