前端性能优化:防抖与节流在项目中的实际应用场景

175 阅读3分钟

最近准备面试看到防抖与节流,看的我云里雾里的,正好有一天写实验室的项目,遇到个很坑的玩意儿,虽然我很早就知道怎么解决,但是一直没想起来这就是防抖思想,果然还得是实践与理论相结合,才能记住这些思想。

防抖与节流

讲我实验室项目之前,我们先回顾一下什么是防抖与节流

防抖(防止抖动,要稳住回城)

防抖: 多次执行,只执行最后一次
作用: 在高频率事件中,在指定的时间只执行最后一次。
简便记忆: 都玩过王者荣耀吧,王者荣耀那个回城事件,是不是多次点击回城或者被别人打断了都不能回城,而且你多次点击回城,只能最后一次才能成功回城,所以要稳住,不能抖动
封装代码实现:

function debounce(option,time){
   let timer = null
   return ()=>{
       //如果多次点击 timer就不为null,就清除前面的定时器执行最后一次
       if(timer) clearTimeout(timer)
       timer = setTimeout(()=>{
           console.log(option)
       },time)
   }
}
Dom.addEventListener('mousemove',debounce('xxxxx',500))

应用场景:比如某些搜索功能,肯定是用户输入完了才搜索,而不是边输入边搜索。还有正则的验证等,等用户输入完了之后再用正则去验证,而不是边输入边验证

节流(节约带宽)

节流: 多次执行,只执行第一次
作用: 在高频率事件中,只是执行一次。
简便记忆: 火箭发射,无论你按多少次发射按钮,就只执行第一次点击的发射的那次按钮
封装代码实现:

function debounce(option,time){
   let timer = null
   return ()=>{
       //刚开始为空timer=null,!timer不未null,进入定时器
       if(!timer){
               现在timer不为null以后再点击,!timer就为Null了
           timer = setTimeout(()=>{
           console.log(option)
           timer =null
           },time)
       }
   }
}
Dom.addEventListener('mousemove',debounce('xxxxx',500))

应用场景:比如项目中添加一条信息,多次点击添加,我们肯定是添加第一次的,多次点击添加按钮不会重复添加。

项目中的防抖与节流

防抖

大家先看看我项目中的抖动:

hospital_escort_system - 微信开发者工具 Stable v1.06.2401020 2024-03-12 14-25-08 (1).gif 可以看到我们多次点击了添加,网络请求也多次,这是网络富裕还好说,网络带宽不富裕,那就遭老罪咯。 解决效果:

hospital_escort_system - 微信开发者工具 Stable v1.06.2401020 2024-03-12 14-29-36.gif 看起来不像传统的那种,但是思想也是和抖动没什么区别,有些网络不好的情况下谁能保证用户不会多点击几次呢?多点击几次添加了相同的的数据,既占用了网络带宽,又添加了多余数据。

防抖解决方案:

不同于传统的定时器操作,其实本质是一样的,我们在用户点击第一次之后我们将button的disabled设置为true,在ajax请求回来之后,我们再将button的disabled的状态设置为false

<AtButton className='AtButton addPatentButton' onClick={this.addPatient} disabled={buttonDisable}>添加</AtButton>
addPatient =()=>{
  const {dispatch} = this.props
  //不准再次点击按钮
  this.setState({buttonDisable:true})
  dispatch({
    type:'patientModel/addPatient',
    //将回调传入
    callback:()=>{
      this.setState({buttonDisable:false})
    }
  })
}
*addPatient({callback},{call,put,select}){
  const data = yield select(state => state.patientModel.patientDetail)
  const response = yield call(patientService.addPatient,data)
  const {code} = response
  if(code ===RESPONSE_OBJ.SUCCESS){
    Taro.showToast({
      title:'添加成功',
      duration:2000,
      icon:'success',
      success:()=>{
        setTimeout(()=>{
        //添加成功之后调用传入的回调函数更改disabled状态
          Taro.navigateBack()
          callback()
        },2000)
      }
    })
  }

节流

节流比如说正则嘛,我们输入的时候,一直弹,烦的很呢,我们就在提交的时候进行正则验证,就不一直弹校验不通过了,现在antd下都有正则校验,而Taro则要手动校验烦的很,我们再输入的时候不做正则校验,提交的时候做正则校验,这样避免了烦人的提醒 hospital_escort_system - 微信开发者工具 Stable v1.06.2401020 2024-03-12 15-00-12.gif

总结

防抖与节流都是前端性能优化的重要部分,大家看网上的也可能和我一样迷迷糊糊记不住,还得是实践与理论相结合才得行 image.png