Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

请加上 shouldComponentUpdate

  在 React 中,父组件的渲染会触发子组件的渲染。如果父组件的渲染频率非常高,子组件又非常复杂,那就会在每次渲染时候带来不必要的性能开销。如果将 React 的组件视为 UI=f(props,state,context),我们就可以在 shouldComponentUpdate 中做一次自变量改变的检测。
  下面的代码中有两个组件 A 和 B,它们是嵌套关系。A 是父组件,它的渲染频率很高;B 是子组件,它是一个由 5000 个元素组成的列表。这时候如果没有 shouldComponentUpdate 就会在每一帧执行一次 B 的 render,这是一个非常慢的操作。 <!DOCTYPE html> <head> <base href="https://cdn.bootcss.com" /> <script src="/react/0.14.0-beta3/JSXTransformer.js"></script> <script src="/react/0.14.0-beta3/react.min.js"></script> </head> <body> <script type="text/jsx"> class A extends React.Component { constructor() { super(); this.state = {}; var i = 0; var begin = Date.now(); setInterval(() => { var fps = Math.round(i++ / (Date.now() - begin) * 1000); this.setState({ fps }); }); } render() { return <div><h1>FPS: {this.state.fps}</h1><B/></div>; } } class B extends React.Component { constructor() { super(); var init = (value, index) => Math.sin(index + 1); var data = Array.from({ length: 5000 }, init); this.state = { data }; } // shouldComponentUpdate(props, state, context) { // return ( // JSON.stringify([ props, state, context ]) !== // JSON.stringify([ this.props, this.state, this.context ]) // ); // } render() { return ( <ul> { this.state.data.map(item => <li key={item}>{item}</li> ) } </ul> ); } } React.render(<A/>, document.body); </script> </body>   下图中分别是无 shouldComponentUpdate(左)和有 shouldComponentUpdate(右)的测试结果。

  很显然,加上 shouldComponentUpdate 后的渲染速度比原来快得多。而且上面代码中的 shouldComponentUpdate 已经是写得非常通用的了,只是暴力地把组件的自变量转换成 JSON 后作比较。
  纯数据的 diff 的结果只是希望得到一个标识是否有更新的布尔值,这比 VDOM 的 diff 要快得多。所以我们应该尽可能地给组件加上 shouldComponentUpdate,并且不要在 render 中访问 props、state、context 之外的数据,以免破坏组件的幂等性。
  另外,shouldComponentUpdate 可能会带来其他问题。上面的例子中只是两层嵌套,所以看不出有什么问题。如果是多层嵌套,最外层的数据通过 context 直接传给最内层的组件,那么如果中间层阻止了渲染就会导致内层组件的更新不及时。所以我们应该避免使用 context 这种东西,虽然一层层地通过 props 传递数据的做法很恶心,但这至少可以让整棵组件树的更新传递更直观。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^