将span隐藏的函数_前端性能优化之函数防抖与截流

114a7463d361bbedce109bd99b525561.png

在前端开发当中,我们都知道有些交互事件,会频繁触发。这样会导致我们的页面渲染性能,如果频繁触发接口调用的话,会直接导致服务器性能的浪费。话不多说,盘它!

5d2ee6bc7fcb92400490c24b1247226f.png

我们先简单列一下

onresize onmousemove onkeydown srcoll onkeyup


这里我是用键盘事件 keyup作为测试

我们先看一段测试用例

<ul>
  <li>
    未做处理:<input type="text" id="ipt">
    <div>函数被调用:<span id="count">0</span>次</div>
  </li>
</ul>
const oCount = document.getElementById('count');
const oIpt = document.getElementById('ipt');
let init = 0
oIpt.onkeyup = function() { 
  oCount.innerText = ++init
}

看一下输入时候的运行效果。

73b102d8b38560978ed35bf887ef1e0d.gif

我们不难发现,每次输入都会触发事件的执行。如果我们用这样的方式去检测:当前用户输入的用户名是否可用?如此高频率的触发不仅是极大的浪费,而且用户还没有输入完成就检测,对用户的提示也不好。应该等用户输入完了,我们再去触发函数,下面我们优化一下:

// 设置一个默认值 300ms
const oCount2 = document.getElementById('count2');
const oIpt2 = document.getElementById('ipt2');

// 设置一个默认值 300ms
const debounce = (fn, wait = 300) => {
  let time = null
  return function(arguments) {
    const _this = this, args = arguments
    clearTimeout(time)
    time = setTimeout(() => {
      fn.apply(_this, [args])
      // fn.call(_this, args)   //或者使用这个
    }, wait)
  }
}

let init2 = 0
oIpt2.onkeyup = debounce(function() {
  oCount2.innerText = ++init2
}, 500)  //可以自己定义延迟时间间隔

再来看一下比对效果:

3ebb28b80b8cfe47a32d14dd4f176998.gif

可以看到,加了防抖函数之后,当我们在频繁输入的时候,函数并没有执行, 只有在函数指定的间隔内(500ms)不再输入了,才会执行函数。如果在时间间隔之内继续输入,会触发函数重新计数。

函数防抖的概念:在事件触发后的n秒之后,再去执行真正需要执行的函数,如果在这n秒之内事件又被触发,则重新开始计时

也就是说,如果用户在间隔时间内一直触发函数,那么这个防抖函数内部的真正需要执行的函数将永远无法执行。

那有没有什么好点的办法,让用户在输入过程中,既能触发真实需要的函数,又能达到优化的效果?答案是肯定的,那就是:

函数截流

事例代码如下

const oCount3 = document.getElementById('count3');
const oIpt3 = document.getElementById('ipt3');
const oTime = document.getElementById('time');

const throttle = (fn, threshhold = 1000) => {
  let last, deferTimer
  return function(arguments) {
    const _this = this, args = arguments
    let now = +new Date()
    if(last && now < last + threshhold) {
      clearTimeout(deferTimer)
      deferTimer = setTimeout(function () {
          last = now
          fn.call(_this, args)
        }, threshhold)
    } else {
       last = now
         fn.call(_this, args)
    }
  }
}
let init3 = 0
const throttleIpt = throttle(function() {
  let time = new Date().getMinutes() + ':' + new Date().getSeconds()
  oTime.innerText = time
  oCount3.innerText = ++init3
}, 1000)  // 初始化一下

oIpt3.onkeyup = function() {
  throttleIpt()
}

由于我们设置的时间间隔是1000ms也就是1s。我来看一下优化效果:(注意看调用次数和时间上秒的变化)

021bc400ce405e9c85442ade640d1639.gif

可以看到,任由我们怎么输入,函数会按照我们设定的时间(1s),每秒执行一次。你可以设置更大。

函数截流的概念:规定好一个单位时间,触发函数一次。如果在这个单位时间内触发多次函数的话,只有一次是可被执行的。想执行多次的话,只能等到下一个周期里

他们之间的优缺点,等我下次总结吧!

下面 的你值得拥有:

沈志勇说

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值