浅谈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 相关文章推荐
Jquery + Ajax调用webService实例代码(asp.net)
Aug 27 Javascript
有趣的javascript数组定义方法
Sep 10 Javascript
javascript显式类型转换实例分析
Apr 25 Javascript
javascript实现控制文字大中小显示
Apr 28 Javascript
JavaScript如何动态创建table表格
Aug 02 Javascript
jquery实现的回旋滚动效果完整实例【附demo源码下载】
Sep 20 Javascript
Bootstrap CSS布局之按钮
Dec 17 Javascript
Chrome浏览器的alert弹窗禁止再次弹出后恢复的方法
Dec 30 Javascript
微信小程序实现点击图片旋转180度并且弹出下拉列表
Nov 27 Javascript
Nuxt.js开启SSR渲染的教程详解
Nov 30 Javascript
React组件对子组件children进行加强的方法
Jun 23 Javascript
VueJS 取得 URL 参数值的方法
Jul 19 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处理数据库数据如何将数据返回客户端并显示当前状态
2016/02/16 PHP
php解决和避免form表单重复提交的几种方法
2016/08/31 PHP
详解php语言最牛掰的Laravel框架
2017/11/20 PHP
thinkPHP5框架auth权限控制类与用法示例
2018/06/12 PHP
PHP基于timestamp和nonce实现的防止重放攻击方案分析
2019/07/26 PHP
javascript对象的property和prototype是这样一种关系
2007/03/24 Javascript
javascript 三种方法实现获得和设置以及移除元素属性
2013/03/20 Javascript
javascript学习笔记之10个原生技巧
2014/05/21 Javascript
Bootstrap树形控件使用方法详解
2016/01/27 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(1)
2017/02/20 Javascript
vue项目中axios使用详解
2018/02/07 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
2018/02/23 Javascript
vue.js层叠轮播效果的实例代码
2018/11/08 Javascript
详解TypeScript+Vue 插件 vue-class-component的使用总结
2019/02/18 Javascript
javascript实现点击产生随机图形
2021/01/25 Javascript
[47:55]Ti4第二日主赛事败者组 NaVi vs EG 1
2014/07/20 DOTA
在Python中使用成员运算符的示例
2015/05/13 Python
python实现文件路径和url相互转换的方法
2015/07/06 Python
Python基于select实现的socket服务器
2016/04/13 Python
浅析Python中的for 循环
2016/06/09 Python
Python嵌套式数据结构实例浅析
2019/03/05 Python
django创建超级用户时指定添加其它字段方式
2020/05/14 Python
详解python安装matplotlib库三种失败情况
2020/07/28 Python
详解CSS3 rem(设置字体大小) 教程
2017/11/21 HTML / CSS
adidas美国官网:adidas US
2016/09/21 全球购物
酒店管理自荐信
2013/10/23 职场文书
学习十八大报告感言
2014/02/28 职场文书
简历中个人自我评价分享
2014/03/15 职场文书
超市优秀员工事迹材料
2014/05/01 职场文书
学习方法演讲稿
2014/05/10 职场文书
公司员工宿舍管理制度
2015/08/07 职场文书
超市主管竞聘书
2015/09/15 职场文书
安全生产协议书
2016/03/22 职场文书
MySQL基础(一)
2021/04/05 MySQL
python for循环赋值问题
2021/06/03 Python
低门槛开发iOS、Android、小程序应用的前端框架详解
2021/10/16 Javascript