React函数式组件的性能优化

优化思路 拼多多优惠券
主要优化的方向有2个:
减少重新的次数 。因为在 React 里最重(花时间最长)的一块就是 (简单的可以理解为 diff),如果不 ,就不会。减少计算的量 。主要是减少重复计算,对于函数式组件来说 , 每次都会重新从头开始执行函数调用 。
在使用类组件的时候,使用的 React 优化 API 主要是:e和
那么在函数式组件中,我们怎么做性能优化?主要用到下面几个方法去优化
React.mo React.memo
看个例子:
我们在父组件中放一个按钮用于修改子标题,并引入Child子组件
可以看到,第一次进来子组件打印了.log('我是子组件')
当点击修改子标题 , Child子组件也打印了,造成了不必要的重复渲染次数
//父组件import {useState} from 'react'import Child from "./Child";const Index = ()=>{const [subTitle, setSubTitle] = useState('我是子标题')const updateSubTitle = ()=>{setSubTitle('修改子标题')}return (函数式组件性能优化{subTitle});}export default Index;//子组件Child.jsconst Child = ()=>{console.log('我是子组件')return (我是子组件)}export default Child
优化一下,使用React.memo包裹子组件
import React from "react";const Child = ()=>{console.log('我是子组件')return (我是子组件)}export default React.memo(Child)
再观察一下,发现Child子组件没有重复渲染了
这里我们再改造一下 , 给Child子组件添加一个事件,然后点击修改子标题按钮 , 发现我们的Child子组件又重新渲染了,这里主要是因为修改子标题的时候函数重新渲染变化,造成子组件重新渲染
// 父组件const Index = ()=>{const [subTitle, setSubTitle] = useState('我是子标题')const updateSubTitle = ()=>{setSubTitle('修改子标题')}const handlerClick = ()=>{console.log('子组件点击')}return (函数式组件性能优化{subTitle});}// Child子组件const Child = (props)=>{console.log('我是子组件')return (我是子组件)}export default React.memo(Child)
优化一下,使用包裹处理子组件的函数,再次点击修改子标题 , 发现Child子组件没有重新再渲染
// 父组件const Index = ()=>{const [subTitle, setSubTitle] = useState('我是子标题')const updateSubTitle = ()=>{setSubTitle('修改子标题')}const handlerClick = useCallback(()=>{console.log('子组件点击')},[])return (函数式组件性能优化{subTitle});}export default Index;
这里关于的用法
const callback = () => {doSomething(a, b);}const memoizedCallback = useCallback(callback, [a, b])
把函数以及依赖项作为参数传入 ,它将返回该回调函数的版本,这个只有在依赖项有变化的时候才会更新 。
用于计算结果缓存
我们先看个例子,在之前基础上添加一个计算函数 , 然后点击更新子标题,发现重新计算了,也就是每次渲染都会造成重复计算,如果是计算量比较大的情况下,会极大的影响性能
// 父组件const Index = ()=>{const [subTitle, setSubTitle] = useState('我是子标题')const updateSubTitle = ()=>{setSubTitle('修改子标题')}const handlerClick = useCallback(()=>{console.log('子组件点击')},[])const calcCount = ()=>{let totalCount = 0for(let i=0;i<10000;i++){totalCount+=i}console.log('totalCount',totalCount)return totalCount}const count = calcCount()return (函数式组件性能优化{subTitle}count:{count});}
优化一下,使用缓存计算结果,我们再次点击修改子标题按钮,可以发现函数不再重复计算
const calcCount = ()=>{let totalCount = 0for(let i=0;i<10000;i++){totalCount+=i}console.log('totalCount',totalCount)return totalCount}const count = useMemo(calcCount,[])
最后,需要注意的是不能盲目的使用,要根据具体的场景,比如对于一个数据计算量比较大 , 那么使用是比较适用的 , 而对于普通的一些值得计算,可以不使用,因为本身也是会消耗一些性能,盲目使用反而会适得其反
参考阅读文章最后
本文作者阿健Kerry , 高级前端工程师,转载请注明出处 。如果觉得本文对你有帮助 , 记得点赞三连哦,也可以扫码关注我新建立的前端技术公众号【有你前端】,之后我所有文章会同步发到这个公众号上面 。另外,我建了一个可以帮助咱们程序员脱单的公众号,每周都会推送几个优秀的单身小姐姐,如果你是程序员技术好又正好是单身 , 那你可以下面扫码关注【缘来你是程序猿】公众号开启你的脱单之旅 。
【React函数式组件的性能优化】

React函数式组件的性能优化

文章插图