浅谈JS函数节流防抖


Posted in Javascript onOctober 18, 2017

在前端开发中有一部分的用户行为会频繁的触发事件执行,而对于DOM操作、资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃。函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的。

函数节流(throttle)

函数节流就是预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行。好像水滴攒到一定重量才会落下一样。

场景:

  • 窗口调整(resize)
  • 页面滚动(scroll)
  • 抢购疯狂点击(mousedown)

实现:

function throttle(method, delay){
  var last = 0;
  return function (){
    var now = +new Date();
    if(now - last > delay){
      method.apply(this,arguments);
      last = now;
    }
  }
}

document.getElementById('throttle').onclick = throttle(function(){console.log('click')},2000);

underscore实现:

_.throttle = function(func, wait, options) {
  var context, args, result;
  var timeout = null;
  var previous = 0;
  if (!options) options = {};
  var later = function() {
    previous = options.leading === false ? 0 : _.now();
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  };
  return function() {
    var now = _.now();
    if (!previous && options.leading === false) previous = now;
    //计算剩余时间
    var remaining = wait - (now - previous);
    context = this;
    args = arguments;
    //剩余时间小于等于0或者剩余时间大于等待时间(本地时间变动出现)
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };
};

函数防抖(debounce)

函数防抖就是在函数需要频繁触发情况时,只有足够空闲的时间,才执行一次。好像公交司机会等人都上车后才出站一样。

场景:

  • 实时搜索(keyup)
  • 拖拽(mousemove)

实现:

function debounce(method, delay){
  var timer = null;
  return function(){
    var context = this,args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function(){
      method.apply(context, args);
    },delay);
  }
}

document.getElementById('debounce').onclick = debounce(function(){console.log('click')},2000);

underscore实现:

_.debounce = function(func, wait, immediate) {
  var timeout, args, context, timestamp, result;
  var later = function() {
    var last = _.now() - timestamp;
    if (last < wait && last >= 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      }
    }
  };
  return function() {
    context = this;
    args = arguments;
    timestamp = _.now();
    var callNow = immediate && !timeout;
    if (!timeout) timeout = setTimeout(later, wait);
    if (callNow) {
      result = func.apply(context, args);
      context = args = null;
    }
    return result;
  };
};

函数节流(throttle)和函数防抖(debounce)都是通过延时逻辑操作来提升性能的方法,在前端优化中是常见且重要的解决方式。可以从概念和实际应用中理解两者的区别,在需要的时候选择合适的方法处理。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 操作table,可以新增行和列并且隔一行换背景色代码分享
Jul 05 Javascript
浅析JavaScript中的同名标识符优先级
Dec 06 Javascript
jquery实现倒计时功能
Dec 28 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
May 18 Javascript
jQuery模拟下拉框选择对应菜单的内容
Mar 07 Javascript
JS HTML图片显示Canvas 压缩功能
Jul 21 Javascript
微信小程序 循环及嵌套循环的使用总结
Sep 26 Javascript
Vue中的scoped实现原理及穿透方法
May 15 Javascript
node实现socket链接与GPRS进行通信的方法
May 20 Javascript
vue实现拖拽效果
Dec 23 Javascript
JavaScript canvas实现跟随鼠标移动小球
Feb 09 Javascript
Vue实现下拉加载更多
May 09 Vue.js
用vue封装插件并发布到npm的方法步骤
Oct 18 #Javascript
详解Js中的模块化是如何实现的
Oct 18 #Javascript
JS跳转手机站url的若干注意事项
Oct 18 #Javascript
vue实现手机号码抽奖上下滚动动画示例
Oct 18 #Javascript
Angular.js实现获取验证码倒计时60秒按钮的简单方法
Oct 18 #Javascript
浅谈Node异步编程的机制
Oct 18 #Javascript
js实现随机点名系统(实例讲解)
Oct 18 #Javascript
You might like
PHP通用分页类page.php[仿google分页]
2008/08/31 PHP
zf框架的db类select查询器join链表使用示例(zend框架)
2014/03/14 PHP
php+highchats生成动态统计图
2014/05/21 PHP
搭建pomelo 开发环境
2014/06/24 Javascript
jQuery实现返回顶部功能适合不支持js的浏览器
2014/08/19 Javascript
jquery动态改变div宽度和高度
2015/02/09 Javascript
javascript实现带下拉子菜单的导航菜单效果
2015/05/14 Javascript
javascript数组对象常用api函数小结(连接,插入,删除,反转,排序等)
2016/09/20 Javascript
vue.js初学入门教程(2)
2016/11/07 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
angularjs ui-router中路由的二级嵌套
2017/03/10 Javascript
详解用vue编写弹出框组件
2017/07/04 Javascript
JS中的算法与数据结构之常见排序(Sort)算法详解
2019/08/16 Javascript
Echarts.js无法引入问题解决方案
2020/10/30 Javascript
python实现的生成随机迷宫算法核心代码分享(含游戏完整代码)
2014/07/11 Python
python实现linux下使用xcopy的方法
2015/06/28 Python
浅析Python中的多条件排序实现
2016/06/07 Python
PYTHON压平嵌套列表的简单实现
2016/06/08 Python
python安装twisted的问题解析
2018/08/21 Python
PyCharm设置每行最大长度限制的方法
2019/01/16 Python
使用Python制作新型冠状病毒实时疫情图
2020/01/28 Python
Python3.7实现验证码登录方式代码实例
2020/02/14 Python
使用Pycharm分段执行代码
2020/04/15 Python
基于python调用jenkins-cli实现快速发布
2020/08/14 Python
新加坡网上化妆品店:Best Buy World
2018/05/18 全球购物
心理学专业毕业生推荐信范文
2013/11/21 职场文书
简历的个人自我评价范文
2014/01/03 职场文书
技校个人求职信范文
2014/01/25 职场文书
决心书范文
2014/03/11 职场文书
汽车技术服务与贸易专业求职信
2014/07/20 职场文书
作文评语集锦
2014/12/25 职场文书
2015年度优秀员工自荐书
2015/03/06 职场文书
结婚喜宴迎宾词
2015/08/10 职场文书
解决thinkphp6(tp6)在状态码500下不报错,或者显示错误“Malformed UTF-8 characters”的问题
2021/04/01 PHP
Dubbo+zookeeper搭配分布式服务的过程详解
2022/04/03 Java/Android
SQL语句中EXISTS的详细用法大全
2022/06/25 MySQL