react性能优化

1.(单个react组件性能优化)render里面尽量减少新建变量和bind函数,传递参数是尽量减少传递参数的数量。***

在这里插入图片描述
第一种是在构造函数中绑定this,第二种是在render()函数里面绑定this,第三种就是使用箭头函数,都能实现上述方法;但是第一种的性能最好。

因为第一种,构造函数每一次渲染的时候只会执行一遍;
而第二种方法,在每次render()的时候都会重新执行一遍函数;
第三种方法的话,每一次render()的时候,都会生成一个新的箭头函数,即使两个箭头函数的内容是一样的。

2.多个react组件性能优化,key的优化

react组件在装载过程中,react通过在render方法在内存中产生一个树形结构,树上的节点代表一个react组件或者原生的Dom元素,这个树形结构就是我们所谓的Vitural Dom,react根据这个来渲染产生浏览器的Dom树。

react在更新阶段对比原有的Vitural Dom和新生成的Vitural Dom,找出不同之处,在根据不同来渲染Dom树。
在这里插入图片描述

我们想把A组件更新成B组件,react在做比较的时候,发现最外面的根结点不一样,直接就废掉了之前的

节点,包括里面的子节点,这是一个巨大的浪费,所以在开发过程中,我们应该尽量避免上面的情况,不要将包裹节点的类型随意改变
多个子组件情况
简单来说,其实这一个Key就是react组件的身份证号。
在这里插入图片描述
不过现在,react也会提醒我们不要忘记使用key,如果没有加,在浏览器中会报错。
在这里插入图片描述
**

3.不要使用内联函数定义

**
如果我们使用内联函数,每次调用“render”函数时都会创建一个新的函数实例。
当 React 进行虚拟 DOM diffing 时,它每次都会找到一个新的函数实例;因此在渲染阶段它会会绑定新函数并将旧实例扔给垃圾回收。
因此直接绑定内联函数就需要额外做垃圾回收和绑定到 DOM 的新函数的工作。
在这里插入图片描述
上面的函数创建了内联函数。每次调用 render 函数时都会创建一个函数的新实例,render 函数会将该函数的新实例绑定到该按钮。
此外最后一个函数实例会被垃圾回收,大大增加了 React 应用的工作量。
所以不要用内联函数,而是在组件内部创建一个函数,并将事件绑定到该函数本身。这样每次调用 render 时就不会创建单独的函数实例了,参考组件如
在这里插入图片描述

4.避免使用内联样式属性

使用内联样式时浏览器需要花费更多时间来处理脚本和渲染,因为它必须映射传递给实际 CSS 属性的所有样式规则。
将内联样式附加到组件。添加的内联样式是 JavaScript 对象而不是样式标记。
样式 backgroundColor 需要转换为等效的 CSS 样式属性,然后才应用样式。这样就需要额外的脚本处理和 JS 执行工作。
更好的办法是将 CSS 文件导入组件

5.避免 componentWillMount() 中的异步请求

componentWillMount 是在渲染组件之前调用的。这个函数用的不多,可用来配置组件的初始配置,但使用 constructor 方法自己也能做到。
该方法无法访问 DOM 元素,因为组件还没挂载上来。

一些开发人员认为这个函数可以用来做异步数据 API 调用,但其实这没什么好处。由于 API 调用是异步的,因此组件在调用 render 函数之前不会等待 API 返回数据。于是在初始渲染中渲染组件时没有任何数据。
在这里插入图片描述
在上面的代码中,我们正在进行异步调用以获取数据。由于数据调用是异步的,需要一段时间才能获取到。

在检索数据时 React 会触发组件的 render 函数。因此第一个调用的渲染仍然不包含它所需的数据。

这样一开始渲染组件没有数据,然后检索数据,调用 setState,还得重新渲染组件。在 componentWillMount 阶段进行 AJAX 调用没有好处可言。
我们应避免在此函数中发出 Async 请求。这些函数和调用可以延迟到 componentDidMount 生命周期事件里。

6.在 Constructor 的早期绑定函数

当我们在 React 中创建函数时,我们需要使用 bind 关键字将函数绑定到当前上下文。绑定可以在构造函数中完成,也可以在我们将函数绑定到 DOM 元素的位置上完成。两者之间似乎没有太大差异,但性能表现是不一样的。
在这里插入图片描述
在上面的代码中,我们在 render 函数的绑定期间将函数绑定到按钮上。问题在于,每次调用 render 函数时都会创建并使用绑定到当前上下文的新函数,但在每次渲染时使用已存在的函数效率更高。优化方案如下:
在这里插入图片描述
最好在构造函数调用期间使用绑定到当前上下文的函数覆盖 handleButtonClick 函数。这将减少将函数绑定到当前上下文的开销,无需在每次渲染时重新创建函数,从而提高应用的性能。

7.优化 React 中的条件渲染

很多情况下在我们可能会渲染或不渲染特定元素,这时可以用条件渲染。
在这里插入图片描述
优化为
在这里插入图片描述

8.不要在 render 方法中导出数据

Render 方法是 React 开发人员最熟悉的生命周期事件。和其他生命周期事件不一样的是,我们的核心原则是将 render() 函数作为纯函数。

纯函数意味着我们应该确保 setState 和查询原生 DOM 元素等任何可以修改应用状态的东西不会被调用。该函数永远不该更新应用的状态。

更新组件状态的问题在于,当状态更新时会触发另一个 render 循环,后者在内部会再触发一个 render 循环,以此类推。
在这里插入图片描述
在上面的代码中,每次调用 render 函数时都会更新状态。状态更新后组件将立即重新渲染。因此更新状态会导致 render 函数的递归调用。
render 函数应保持纯净,以确保组件以一致的方式运行和渲染

9.用 CSS 动画代替 JavaScript 动画

在 HTML 5 和 CSS 3 出现之前,动画曾经是 JavaScript 的专属,但随着 HTML 5 和 CSS 3 的引入情况开始变化。现在动画甚至可以由 CSS 3 来处理了。
我们可以制定一些规则:
如果 CSS 可以实现某些 JS 功能,那就用 CSS。
理由如下:

  1. 破损的 CSS 规则和样式不会导致网页损坏,而 JavaScript 则不然。
  2. 解析 CSS 是非常便宜的,因为它是声明性的。我们可以为样式并行创建 内存中的表达,可以推迟样式属性的计算,直到元素绘制完成。
  3. 为动画加载 JavaScript 库的成本相对较高,消耗更多网络带宽和计算时间。
  4. 虽然 JavaScript 可以提供比 CSS 更多的优化,但优化过的 JavaScript 代码也可能卡住 UI 并导致 Web 浏览器崩溃。

10.React 组件的服务端渲染

服务端渲染可以减少初始页面加载延迟。
我们可以让网页从服务端加载初始页面,而不是在客户端上渲染。这样对 SEO 非常有利。服务端渲染是指第一个组件显示的内容是从服务器本身发送的,而不是在浏览器级别操作。之后的页面直接从客户端加载。
这样我们就能把初始内容放在服务端渲染,客户端只按需加载部分页面。
其好处包括:

  1. 性能:初始页面内容和数据是从服务器本身加载的,因此我们不需要添加加载器和下拉列表,而是等待初始页面加载完毕后再加载初始组件。
  2. SEO 优化:爬虫在应用初始加载时查找页面内容。在客户端渲染时初始 Web 页面不包含所需的组件,这些组件需要等 React 脚本等文件加载完毕后才渲染出来。

11.shouldComponentUpdate避免组件无意义渲染

state有时候很不听话,在某些时候,我不想他渲染,偏偏react非常智能的帮我们重复渲染。
比如最常见的就是传递的对象为空,组件依旧渲染了一次或者多次。
使用shouldComponentUpdate钩子,根据具体的业务状态,减少不必要的props变化导致的渲染。如一个不用于渲染的props导致的update。
另外, 也要尽量避免在shouldComponentUpdate 中做一些比较复杂的操作, 比如超大数据的pick操作等。
shouldComponentUpdate是react提供的生命周期函数,他发生在接收到新的props的时候。
在这里插入图片描述
组件生命周期是有顺序的,首先挂载组件,挂载成功完成第一次渲染,然后传递新的props,则会触发componentWillRecevieProps,执行重新渲染的周期,直至渲染完成。

组件生命周期是有顺序的,首先挂载组件,挂载成功完成第一次渲染,然后传递新的props,则会触发componentWillRecevieProps,执行重新渲染的周期,直至渲染完成。
在你的组件内部加上这段代码
component.js
在这里插入图片描述
这里用到了_.isEqual和_.isEmpty,.isEqual判断当前传进来的值和下一次传递的值是不是相等,是则返回true,.isEmpty判断当前传递进来的对象是不是为空,为空则返回true。
.isEqual和.isEmpty是 lodash 插件里面的函数,这是个轻巧的JavaScript函数插件,可以处理多种常见的数据操作,当然还有一个更多功能的插件。 在你的react项目的入口js导入lodash,因为lodash函数是全局的,所以只需要在入口导入一次即可。 • 合理设计state,不需要渲染的state,尽量使用实例成员变量。 不需要渲染的props,合理使用context机制,或公共模块(比如一个单例服务)变量来替换。 • 拆分组件是有利于复用和组件优化的。 • 生成虚拟DOM并进行比对发生在render()后,而不是render()前。