浅谈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 相关文章推荐
js arguments对象应用介绍
Nov 28 Javascript
JS.getTextContent(element,preformatted)使用介绍
Sep 21 Javascript
js数组的基本用法及数组根据下标(数值或字符)移除元素
Oct 20 Javascript
Javascript学习笔记之相等符号与严格相等符号
Nov 23 Javascript
JavaScript获取网页、浏览器、屏幕高度和宽度汇总
Dec 18 Javascript
JavaScript更改字符串的大小写
May 07 Javascript
详解基于Bootstrap扁平化的后台框架Ace
Nov 27 Javascript
js获取鼠标位置实例详解
Dec 09 Javascript
微信jssdk在iframe页面失效问题的解决措施
Mar 03 Javascript
vue使用stompjs实现mqtt消息推送通知
Jun 22 Javascript
Vue 2.0学习笔记之Vue中的computed属性
Oct 16 Javascript
JavaScript事件委托实现原理及优点进行
Aug 29 Javascript
用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
德生S2000电路分析
2021/03/02 无线电
如何使用PHP中的字符串函数
2006/11/24 PHP
深思 PHP 数组遍历的差异(array_diff 的实现)
2008/03/23 PHP
php与php MySQL 之间的关系
2009/07/17 PHP
php数据库抽象层 PDO
2011/05/07 PHP
Nginx下配置codeigniter框架方法
2015/04/07 PHP
详解PHP对象的串行化与反串行化
2016/01/24 PHP
Yii框架响应组件用法实例分析
2019/09/04 PHP
Firefox 无法获取cssRules 的解决办法
2006/10/11 Javascript
抽出www.templatemonster.com的鼠标悬停加载大图模板的代码
2007/07/11 Javascript
纯js网页画板(Graphics)类简介及实现代码
2012/12/24 Javascript
js在输入框屏蔽按键,只能键入数字的示例代码
2014/01/03 Javascript
jQuery中:submit选择器用法实例
2015/01/03 Javascript
JavaScript时间转换处理函数
2015/04/14 Javascript
jQuery实现的纵向下拉菜单实例详解【附demo源码下载】
2016/07/09 Javascript
JS判断输入字符串长度实例代码(汉字算两个字符,字母数字算一个)
2016/08/02 Javascript
详解js运算符单竖杠“|”与“||”的用法和作用介绍
2016/11/04 Javascript
JS实现复制功能
2017/03/01 Javascript
Vue ElementUI之Form表单验证遇到的问题
2017/08/21 Javascript
layer.open提交子页面的form和layedit文本编辑内容的方法
2019/09/27 Javascript
ubuntu中配置pyqt4环境教程
2017/12/27 Python
PyQt5 QSerialPort子线程操作的实现
2018/04/21 Python
详解pandas安装若干异常及解决方案总结
2019/01/10 Python
解决Python中定时任务线程无法自动退出的问题
2019/02/18 Python
对pyqt5之menu和action的使用详解
2019/06/20 Python
Python利用scapy实现ARP欺骗的方法
2019/07/23 Python
Win10下用Anaconda安装TensorFlow(图文教程)
2020/06/18 Python
python 删除系统中的文件(按时间,大小,扩展名)
2020/11/19 Python
python中绕过反爬虫的方法总结
2020/11/25 Python
matplotlib之pyplot模块之标题(title()和suptitle())
2021/02/22 Python
环境建议书
2015/02/04 职场文书
小班上学期个人总结
2015/02/12 职场文书
全国助残日活动总结
2015/05/11 职场文书
创业的9条正确思考方式
2019/08/26 职场文书
python爬虫之爬取笔趣阁小说
2021/04/22 Python
Java 超详细讲解设计模式之中的抽象工厂模式
2022/03/25 Java/Android