阅读 941
✨性能优化之防抖节流篇

✨性能优化之防抖节流篇

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战

前言

防抖节流作为前端面试经典手撕代码题,掌握防抖和节流是一个前端开发人员工程能力的体现,不会封装防抖和节流?一起来学习吧~🙆‍♂️

防抖(debounce)

基本概念

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

举个🌰子

我们在搜索框输入关键词进行搜索时,就会发送ajax请求,然后展示在列表,这是一个很常见的场景,接下来我们来模拟一下:

  <span>防抖案例</span>
  <input type="text">
复制代码
    const input = document.querySelector('input')
    input.addEventListener('keyup',function(){
    // 模拟ajax请求
      console.log(input.value);
    })
复制代码

20210814_180916.gif 我们会发现每次只要按下键盘都会发送ajax请求,然而这是非常浪费资源的,我们应该在用户输入完字符后一段时间再发送ajax请求,我们来优化一下~

    const input = document.querySelector('input')
    let timer = null
    input.addEventListener('keyup',function(){
      if(timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(()=>{
        // 模拟ajax请求
        console.log(input.value);
        // 清空定时器
        timer = null
      },500)
    })
复制代码

20210814_182522.gif 我们通过演示可以发现,当你在频繁的输入时,并不会发送请求,只有当你在500ms内没有输入时,才会执行函数。如果停止输入但是在指定间隔内又输入,会重新触发计时。这样我们的防抖功能就实现啦~

防抖就好像是英雄释放技能时的读条,技能读条没读完再次使用该技能就会重新读条。

封装防抖函数

上面我们只对该输入框做了防抖,如果有多个输入框需要做防抖,我们不应该把这个防抖功能再实现一次,应该封装一个防抖函数,该使用防抖的时候调用它即可,我们来尝试吧~

    // 封装防抖函数
    function debounce(fn,delay = 500){
      let timer = null
      return function(){
        if(timer) {
          clearTimeout(timer)
        }
        timer = setTimeout(()=>{
          fn.apply(this,arguments)
          timer = null
        },delay)
      }
    }
    // 使用
    input.addEventListener('keyup',debounce(function() {
      console.log(input.value);
    },500))
复制代码

节流(throttle)

基本概念

规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

举个🌰子

拖拽一个元素时,要随时拿到该元素被拖拽的位置,如果没有节流,只要该元素移动1丢丢,哪怕是1px,都会获取当前拖拽的位置,这是非常消耗性能的,容易造成卡顿。 20210814_202336.gif 那我们就来优化一下,使用节流,每500ms获取当前元素的位置,来看代码:

    const div1 = document.querySelector('div')
    let timer = null
    div1.addEventListener('drag',function(e){
      if(timer) {
        return
      }
      timer = setTimeout(()=>{
        console.log(e.offsetX,e.offsetY);
        timer = null
      },500)
    })
复制代码

这样我们的节流操作就做好啦,来看效果~

20210814_202957.gif

节流就好像是你在玩吃鸡时,即使你猛戳开火键,子弹也只会以预定的速度射出,这么样是不是很好理解。

封装节流函数

    // 封装节流
    function throttle(fn,delay = 500) {
      let timer = null
      return function() {
        if(timer) {
          return
        }
        timer = setTimeout(()=>{
          fn.apply(this,arguments)
          timer = null
        },delay)
      }
    }
    // 使用
    div1.addEventListener('drag',throttle(function(e){
      console.log(e.offsetX,e.offsetY);
    },500))
复制代码

最后

⚽本文介绍了性能优化中的防抖节流的概念以及如何使用~
⚾如果这篇文章对你有帮助的话,麻烦点赞收藏哟~
🏀GitHub 博客地址: github.com/Awu1227
🏉笔者还有其他专栏,欢迎阅读~
🏐玩转CSS之美
🎱Vue从放弃到入门
🎳深入浅出JavaScript

文章分类
前端