加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

React 性能优化技巧总结

发布时间:2019-02-26 14:03:13 所属栏目:建站 来源:落在起风的地方
导读:本文将从 render 函数的角度总结 React App 的优化技巧。需要提醒的是,文中将涉及 React 16.8.2 版本的内容(也即 Hooks),因此请至少了解 useState 以保证食用效果。 正文开始。 当我们讨论 React App 的性能问题时,组件的渲染速度是一个重要问题。在进

我们可以注意到,当状态值不再改变之后,render 的调用就停止了。

总结:对函数式组件来说,状态值改变时才会触发 render 函数的调用。

2. 父容器重新渲染时

  1. import React from "react";  
  2. import ReactDOM from "react-dom";  
  3.   
  4. class App extends React.Component {  
  5.   state = { name: "App" };  
  6.   render() {  
  7.     return (  
  8.       <div className="App">  
  9.         <Foo />  
  10.         <button onClick={() => this.setState({ name: "App" })}>  
  11.           Change name  
  12.         </button>  
  13.       </div>  
  14.     );  
  15.   }  
  16. }  
  17.   
  18. function Foo() {  
  19.   console.log("Foo render");  
  20.   
  21.   return (  
  22.     <div>  
  23.       <h1> Foo </h1>  
  24.     </div>  
  25.   );  
  26. }  
  27.   
  28. const rootElement = document.getElementById("root");  
  29. ReactDOM.render(<App />, rootElement);  

只要点击了 App 组件内的 Change name 按钮,就会重新 render。而且可以注意到,不管 Foo 具体实现是什么,Foo 都会被重新渲染。

总结:无论组件是继承自 React.Component 的 class 组件还是函数式组件,一旦父容器重新 render,组件的 render 都会再次被调用。

在「render」过程中会发生什么?

只要 render 函数被调用,就会有两个步骤按顺序执行。这两个步骤非常重要,理解了它们才好知道如何去优化 React App。

Diffing

在此步骤中,React 将新调用的 render 函数返回的树与旧版本的树进行比较,这一步是 React 决定如何更新 DOM 的必要步骤。虽然 React 使用高度优化的算法执行此步骤,但仍然有一定的性能开销。

Reconciliation

基于 diffing 的结果,React 更新 DOM 树。这一步因为需要卸载和挂载 DOM 节点同样存在许多性能开销。

开始我们的 Tips

Tip #1:谨慎分配 state 以避免不必要的 render 调用

我们以下面为例,其中 App 会渲染两个组件:

  1. CounterLabel  
  2. List  
  1. import React, { useState } from "react";  
  2. import ReactDOM from "react-dom";  
  3.   
  4. const ITEMS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];  
  5.   
  6. function App() {  
  7.   const [count, setCount] = useState(0);  
  8.   const [items, setItems] = useState(ITEMS);  
  9.   return (  
  10.     <div className="App">  
  11.       <CounterLabel count={count} increment={() => setCount(count + 1)} />  
  12.       <List items={items} />  
  13.     </div>  
  14.   );  
  15. }  
  16.   
  17. function CounterLabel({ count, increment }) {  
  18.   return (  
  19.     <>  
  20.       <h1>{count} </h1>  
  21.       <button onClick={increment}> Increment </button>  
  22.     </>  
  23.   );  
  24. }  
  25.   
  26. function List({ items }) {  
  27.   console.log("List render");  
  28.   
  29.   return (  
  30.     <ul>  
  31.       {items.map((item, index) => (  
  32.         <li key={index}>{item} </li>  
  33.       ))}  
  34.     </ul>  
  35.   );  
  36. }  
  37.   
  38. const rootElement = document.getElementById("root");  
  39. ReactDOM.render(<App />, rootElement);  

执行上面代码可知,只要父组件 App 中的状态被更新, CounterLabel 和 List 就都会更新。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读