浅谈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传值 判断
Oct 26 Javascript
jquery 表单进行客户端验证demo
Aug 24 Javascript
jquery实现网页查找功能示例分享
Feb 12 Javascript
jQuery中的height innerHeight outerHeight区别示例介绍
Jun 15 Javascript
JavaScript charCodeAt方法入门实例(用于取得指定位置字符的Unicode编码)
Oct 17 Javascript
JQuery的Ajax中Post方法传递中文出现乱码的解决方法
Oct 21 Javascript
HTML5使用DeviceOrientation实现摇一摇功能
Jun 05 Javascript
JS+CSS实现下拉列表框美化效果(3款)
Aug 15 Javascript
JavaScript实现非常简单实用的下拉菜单效果
Aug 27 Javascript
jQuery实现简单的文件上传进度条效果
Mar 26 Javascript
小程序实现选择题选择效果
Nov 04 Javascript
js实现数字跳动到指定数字
Aug 25 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的范围解析操作符(::)的含义分析说明
2011/07/03 PHP
弹出模态框modal的实现方法及实例
2017/09/19 PHP
thinkPHP5框架实现基于ajax的分页功能示例
2018/06/12 PHP
PHP PDOStatement::errorCode讲解
2019/01/31 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
PHP数组实际占用内存大小原理解析
2020/12/11 PHP
javascript中使用replaceAll()函数实现字符替换的方法
2010/12/25 Javascript
简短几句 通俗解释javascript的闭包
2011/01/17 Javascript
Extjs优化(二)Form表单提交通用实现
2013/04/15 Javascript
jquery实现的简单二级菜单效果代码
2015/09/22 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
JavaScript中捕获/阻止捕获、冒泡/阻止冒泡方法
2016/12/07 Javascript
jQuery动态生成不规则表格(前后端)
2017/02/21 Javascript
vue页面离开后执行函数的实例
2018/03/13 Javascript
深入解析koa之中间件流程控制
2019/06/17 Javascript
laypage.js分页插件使用方法详解
2019/07/27 Javascript
JS函数本身的作用域实例分析
2020/03/16 Javascript
JavaScript的垃圾回收机制与内存管理
2020/08/06 Javascript
python实现的登录和操作开心网脚本分享
2014/07/09 Python
Python脚本处理空格的方法
2016/08/08 Python
python实现可以断点续传和并发的ftp程序
2016/09/13 Python
Python3使用PyQt5制作简单的画板/手写板实例
2017/10/19 Python
Python探索之ModelForm代码详解
2017/10/26 Python
Python cookbook(数据结构与算法)将多个映射合并为单个映射的方法
2018/04/19 Python
浅析python redis的连接及相关操作
2019/11/07 Python
html5唤醒APP小记
2019/03/27 HTML / CSS
新加坡最佳婴儿用品店:Mamahood.com.sg
2018/08/26 全球购物
代理协议书
2014/04/22 职场文书
大学生村官考核材料
2014/05/23 职场文书
计算机网络及管理学专业求职信
2014/06/05 职场文书
社会实践的活动方案
2014/08/22 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
个人优缺点总结
2015/02/28 职场文书
红十字会救护培训简讯
2015/07/20 职场文书
《吸血鬼:避世 血猎》官宣4.27发售 系列首款大逃杀
2022/04/03 其他游戏