难度级别:中高级及以上 提问概率:75%
在React项目开发中,面临着比较大的问题就是组件更新以及重复渲染的问题,基于这两点,我们可以在日常开发工作中,可以通过以下几点,来提升React的性能,加快组件更新对比,避免过多的重复渲染问题。
1 为组件设置唯一key值
在React组件更新过程中,React首先会通过虚拟DOM的key值,来对比判断组件是否属于新增组件,还是原来已有的组件,从而更快速的实现更新过程。不过一定要注意的是,key值不要使用列表遍历过程中产生的index值,因为index很可能会在列表元素的删除过程中变得错乱。
2 不使用匿名函数
例如点击某一个按钮,其实目的很简单,就是更新一下状态,所以很多开发人员发现这样做更方便快捷,代码如下
React代码:
<script>
import React from "react"
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '张三'
}
}
render() {
const { name } = this.state;
return (
<>
<span>{ name }</span>
<button onClick={()=>{this.setState({name: '李四'})}}>更新按钮</button>
</>
)
}
}
</script>
这种做法看似方便快捷,是一种优化的写法,但其实使用的是匿名函数。React在render内遇到匿名函数,会触发新的渲染,从而无法使用组件缓存。同时在本案例中,span和button标签本应有一个父标签包裹这两个元素才可以,通常会添加一个div标签做为这两个子标签的父元素。但如果添加一个父div标签,这样做不仅增加了组件的层级,增加了无用的元素标签,它的作用仅仅是防止程序报错,除此之外毫无用处。所以应该使用fragement空标签的方式来包裹这两个子标签,这样不仅防止程序报错,也不会增加任何额外的无用元素。
3 使用shouldComponentUpdate生命周期
如果组件的props或者state更改后,会触发shouldComponentUpdate生命周期的钩子函数,在这个函数中,开发人员可以通过对比props和state的新旧值,来决定是否要继续更新组件。不过在对比过程中,最好是做浅比较,试想一下,组件更新本身就有那么多代码需要执行,如果我们再人为增加深层次props和state比较的话,势必造成组件更新卡顿。同时一定要注意的是,shouldComponentUpdate生命周期内不要做setState的操作,这会引起组件更新死循环。
与shouldComponentUpdate类似的还有React.memo,不过shouldComponentUpdate是类组件中的一个生命周期,memo用于创建函数组件的一个方法。memo同样也可以对传入的props做浅层次比较,但最大的不同是,memo接收2个参数,第二个参数是自定义对比函数,这样就使得在React组件优化过程显得更加灵活。
4 合理利用懒加载
现在虽然比较流行单页面应用,但很多时候,即便是单页面项目也并不是那么简单,会被拆分为多个子组件。这其中有些组件需要首屏加载,其余组件则会在一定的时机条件下才会加载。所以如果把所有的组件都设置为同步加载,那么每次页面初始化的时候,需要加载的主文件体积必定会非常大,这样用户就需要等待更长的时间才能看到页面,严重影响用户体验。
在React项目中,采用Suspense和lazy配合的方式进行非首屏组件懒加载,这样webpack打包的时候就可以将文件进行合理拆分,从而减小主文件的体积,这样做可以使首屏页面更快速的渲染,从而提升用户体验。
5 尽量少的使用内联样式
我们都知道在前端开发中,使用内联样式有非常大的弊端,比如增大HTML文档体积,内联样式不能够被浏览器缓存等。但是在React项目中,内联样式则有更大的弊端,就像这样
React代码:
<script>
render() {
return (
<span style={{"backgroundColor": "red"}}>内联样式</span>
)
}
</script>
backgroundColor最终并不会被浏览器所识别,这就需要花费更多的时间和程序来解析识别并最终渲染为background-color,所以这种比较固定的内联样式应该抽离到CSS文件中。但在面试中还是不能绝对性的回答说不能使用内联样式,毕竟涉及到一些Javascript动画的时候,动态更改元素的某个样式属性值,也是需要使用内联样式的,所以要回答尽量少的使用内联样式。
刷题思考
虽然本小节中关于React项目性能优化给出了一些方案,但在面试中,尤其是面试高级前端开发的话,仅仅回答这些内容肯定是不够的。
比如为组件设置唯一的key值,这个知识点大家都知道,所以面试中要想得高分,就需要比别人总结的方案更多,而且别人已经总结的方案要用自己的语言描述的更清晰,其实也不一定要回答的多么深奥。回到React性能优化这道题上,求职者还可以与Vue对比着来总结回答,这样更能体现出自己更丰富的知识面。
类似考点
除了掌握好本小节中总结的知识点以外,面试官很可能还会提出以下问题,例如你知道Vue项目中都可以做哪些性能优化吗?例如你知道React项目中如何使用immetable来完成性能优化吗?例如你知道连续多次编写setState会发生什么吗?