【JS】【性能优化】防抖和节流

概念

1、防抖(debounce):连续x时间内没有再次触发才执行回调函数。
根据需求场景的不同,分为计时前触发和计时后触发,这里我把它们叫做前置防抖和后置防抖(可能有别的叫法)
在这里插入图片描述
在这里插入图片描述

2、节流(throttle):x时间内的全部触发只执行一次。同样可以有前置和后置。
在这里插入图片描述
在这里插入图片描述

应用场景和区别

这里举例几个实际应用需求,加深对二者的理解和区分

防抖应用场景

修改用户信息时,提交按钮点击过快会造成多次API请求;

节流应用场景

浏览器播放条每1秒计算一次进度;

节流和防抖都可用的应用场景

拖动浏览器窗口大小,造成resize计算过多卡死;
文档编辑中实现实时保存;
input搜索框随用户输入实时更新搜索建议;

综上场景大概可以总结出

用户不停地操作,你想等用户停下来再交互的,用防抖;
用户不停地操作,你想每隔一段时间交互一次的,用节流;

实现

有时间戳和定时器两种实现方式,时间戳我还没有研究过,二者暂时也没发现优劣(欢迎补充指正),所以我就用定时器实现了。

关键思路:
防抖:触发时重新计时;
节流:计时结束标志;

// 防抖前置
  function debounce(fn,time) {
    let timer; 
    return function () {
      clearTimeout(timer); //触发时重新计时
      let callNow = !timer
      timer = setTimeout(() => {
        timer = null; 
      }, time);
      if(callNow){
        fn.apply(this, arguments);
      }
    };
  }
  function callBackDebounce() {
    console.log('防抖:前置执行');
  }
  var submit = document.getElementById('submit');
  submit.addEventListener('click', debounce(callBackDebounce,5000));
// 防抖后置
  function debounce(fn,time) {
    let timeout = null; 
    return function () {
      clearTimeout(timeout); //触发时重新计时
      timeout = setTimeout(() => { 
        fn.apply(this, arguments);
      }, time);
    };
  }
  function callBackDebounce() {
    console.log('防抖:后置执行');
  }

  var submit = document.getElementById('submit');
  submit.addEventListener('click', debounce(callBackDebounce,5000)); 
//节流前置
  function throttle(fn,time) {
    let timer;
    let timeout = true;
    return function () {
      if(timeout){
        fn.apply(this, arguments);
      }
      if(timeout){
        timeout = false;
        timer = setTimeout(() => { 
          clearTimeout(timer);//注意这个clear的位置跟防抖的区别
          timeout = true; //计时结束标志
        }, time);
      }
    };
  }
  function callBackThrottle(e) {
    console.log(e.target.innerWidth, e.target.innerHeight);
  }
  window.addEventListener('resize', throttle(callBackThrottle,2000));
// 节流后置
  function throttle(fn,time) {
    let timer;
    return function () {
      if(!timer){
        timer = setTimeout(() => { 
          fn.apply(this, arguments);
          clearTimeout(timer)//注意这个clear的位置跟防抖的区别
          timer = null; //计时结束标志
        }, time);
      }
    };
  }
  function callBackThrottle(e) {
    console.log(e.target.innerWidth, e.target.innerHeight);
  }
  window.addEventListener('resize', throttle(callBackThrottle,2000));
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值