收藏
评论

【优化】利用函数防抖和函数节流提高小程序性能

    大家好,上次给大家分享了swiper仿tab的小技巧:   https://developers.weixin.qq.com/community/develop/doc/000cc0b94ac5f8dcf4e7666475b804


    今天给大家分享两个有用的函数,《函数防抖和函数节流》


    函数防抖和函数节流是都优化高频率执行js代码的一种手段,因为是js实现的,所以在小程序里也是适用的。


    首先先来理解一下两者的概念和区别:


        函数防抖(debounce)是指事件在一定时间内事件只执行一次,如果在这段时间又触发了事件,则重新开始计时,打个很简单的比喻,比如在打王者荣耀时,一定要连续干掉五个人才能触发hetai kill '五连绝世'效果,如果中途被打断就得重新开始连续干五个人了。


        函数节流(throttle)是指限制某段时间内事件只能执行一次,比如说我要求自己一天只能打一局王者荣耀。

        

        这里也有个可视化工具可以让大家看一下三者的区别,分别是正常情况下,用了函数防抖和函数节流的情况下:http://demo.nimius.net/debounce_throttle/


    适用场景:


        函数防抖

      • 搜索框搜索联想。只需用户最后一次输入完,再发送请求

      • 手机号、邮箱验证输入检测

      • 窗口resize。只需窗口调整完成后,计算窗口大小。防止重复渲染

      • 高频点击提交,表单重复提交


        函数节流

      • 滚动加载,加载更多或滚到底部监听

      • 搜索联想功能


    实现原理

    

        函数防抖

const _.debounce = (func, wait) => {
  let timer;
 
  return () => {
    clearTimeout(timer);
    timer = setTimeout(func, wait);
  };
};


        函数节流

const throttle = (func, wait) => {
  let last = 0;
  return () => {
    const current_time = +new Date();
    if (current_time - last > wait) {
      func.apply(this, arguments);
      last = +new Date();
    }
  };
};


         上面两个方法都是比较常见的,算是简化版的函数


    

    lodash中的 Debounce 、Throttle

    

        lodash中已经帮我们封装好了这两个函数了,我们可以把它引入到小程序项目了,不用全部引入,只需要引入debounce.js和throttle.js就行了,链接:https://github.com/lodash/lodash

        

        
        使用方法可以看这个代码片段,具体的用法可以看上面github的文档,有很详细的介绍:https://developers.weixin.qq.com/s/vjutZpmL7A51



                                                                                                                                                                                            系甘先,得闲饮茶


最后一次编辑于  2019-01-14
收藏

5 个评论

  • Harry?1:0
    Harry?1:0
    2019-05-31
    formSubmit:debounce( function(e){
        console.log(e)
        console.log(this)
    },1000),


    这里把箭头函数替换成 普通的匿名函数 即可

    2019-05-31
    赞同
    回复
  • 鲤子
    鲤子
    2019-04-11

    感谢贡献,在使用过程中遇到了一个问题,就是this的作用域无效,找了很久没找到相关的问题。

    最后用了一个比较繁琐的方法,如果是在page.js里面,可以在onLoad的时候给page外面定义的self重新赋值,将this赋值给self,然后在事件函数里就可以使用self.setData了。如果有更好解决方法,请告知,3Q。

    2019-04-11
    赞同
    回复 8
    • var 友原
      var 友原
      2019-04-12

      用箭头函数吧,这样直接用this就可以了

      2019-04-12
      回复
    • 鲤子
      鲤子
      2019-04-12回复var 友原

      不行吧,这种写法,事件函数里面是没有this作用域的,头疼。。

      // 验证输入的验证码是否为四位纯数字
      _codeValidate: debounce((value) => {
        validateCode({
           value,
           success() {
              self.setData({
                 loginBtn: true
              })
           },
           fail() {
              self.setData({
                 loginBtn: false
              })
           }
        });
      }, 1000),


      2019-04-12
      回复
    • var 友原
      var 友原
      2019-04-12回复鲤子

      _codeValidate: debounce((value) => {
        validateCode({
           value,
           success()=> {
              this.setData({
                 loginBtn: true
              })
           },
           fail()=> {
              this.setData({
                 loginBtn: false
              })
           }
        });
      }, 1000),

      这样试试


      2019-04-12
      回复
    • 鲤子
      鲤子
      2019-04-12回复var 友原

      不是validateCode回调函数的问题,是在debounce回调里面,找不到this的作用域。如果是直接在事件里面用_codeValidate这个函数,直接用箭头函数就能找到this了。

      _codeValidate: debounce((value) => {
        console.log(this)

      this.setData()
      }, 1000),

      2019-04-12
      回复
    • var 友原
      var 友原
      2019-04-12回复鲤子

      那应该跟setTimeout的作用域问题一样了,网上的做法是把

      (value) => {
        validateCode({
           value,
           success()=> {
              this.setData({
                 loginBtn: true
              })
           },
           fail()=> {
              this.setData({
                 loginBtn: false
              })
           }
        });
      }

      当做参数传入

      2019-04-12
      回复
    查看更多(3)
  • 薛~巍
    薛~巍
    2019-04-11

    怎么把我自己写的函数放进来


    2019-04-11
    赞同
    回复
  • 2019-01-15

    赞一个

    2019-01-15
    赞同
    回复
  • 2019-01-14

    表单重复提交还是用状态来表示好吧

    2019-01-14
    赞同
    回复 1
    • var 友原
      var 友原
      2019-01-14

      也可以,不过从性能上讲还是防抖要好一点,加状态只是为了在请求过程中不被重复,请求成功后还是会触发的,而一般请求的速度是很快的,如果重复点击还是会造成重复提交的。

      2019-01-14
      回复
登录 后发表内容