浅谈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 相关文章推荐
关于IE浏览器以及Firefox下的javascript冒泡事件的响应层级
Oct 14 Javascript
Javascript技巧之不要用for in语句对数组进行遍历
Oct 20 Javascript
js函数的引用, 关于内存的开销
Sep 17 Javascript
javaScript对文字按照拼音排序实现代码
Dec 27 Javascript
js实现继承的5种方式
Dec 01 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
Dec 10 Javascript
通过BootStrap-select插件 js jQuery控制select属性变化
Jan 03 Javascript
javascript笔记之匿名函数和闭包
Feb 06 Javascript
原生js实现瀑布流布局
Mar 08 Javascript
jQuery实现炫丽的3d旋转星空效果
Jul 04 jQuery
原生js实现自定义消息提示框
Nov 19 Javascript
用JS写一个发布订阅模式
Nov 07 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
PHP中如何调用webservice的实例参考
2013/04/25 PHP
PHP安全的URL字符串base64编码和解码
2014/06/19 PHP
PHP简单读取PDF页数的实现方法
2016/07/21 PHP
php简单截取字符串代码示例
2016/10/19 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
PHP强制转化的形式整理
2020/05/22 PHP
PHP使用Http Post请求发送Json对象数据代码解析
2020/07/16 PHP
小议Javascript中的this指针
2010/03/18 Javascript
修改jquery里的dialog对话框插件为框架页(iframe) 的方法
2010/09/14 Javascript
web前端开发也需要日志
2010/12/09 Javascript
javascript 基础篇3 类,回调函数,内置对象,事件处理
2012/03/14 Javascript
jQuery中map()方法用法实例
2015/01/06 Javascript
深入理解JS DOM事件机制
2016/08/06 Javascript
javascript深拷贝和浅拷贝详解
2017/02/14 Javascript
详解vue父子模版嵌套案例
2017/03/04 Javascript
JS实现静态页面搜索并高亮显示功能完整示例
2017/09/19 Javascript
Vuex mutitons和actions初使用详解
2019/03/04 Javascript
vue引入微信sdk 实现分享朋友圈获取地理位置功能
2019/07/04 Javascript
微信小程序入门之绘制时钟
2020/10/22 Javascript
python利用拉链法实现字典方法示例
2017/03/25 Python
Anaconda2下实现Python2.7和Python3.5的共存方法
2018/06/11 Python
Python数据可视化教程之Matplotlib实现各种图表实例
2019/01/13 Python
python SocketServer源码深入解读
2019/09/17 Python
Pytorch实现LSTM和GRU示例
2020/01/14 Python
python yield和Generator函数用法详解
2020/02/10 Python
美国礼品卡商城: Gift Card Mall
2017/08/25 全球购物
澳大利亚波西米亚风情网上商店:Czarina
2019/03/18 全球购物
小学生元旦感言
2014/02/26 职场文书
驾驶员安全责任书
2014/07/22 职场文书
创先争优活动承诺书
2014/08/30 职场文书
廉政教育的心得体会
2014/09/01 职场文书
旷工检讨书1000字
2015/01/01 职场文书
python爬不同图片分别保存在不同文件夹中的实现
2021/04/02 Python
解决Django transaction进行事务管理踩过的坑
2021/04/24 Python
tensorflow中的梯度求解及梯度裁剪操作
2021/05/26 Python
Android自定义双向滑动控件
2022/04/19 Java/Android