浅谈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获取tr中控件值并操作tr实现思路
Mar 27 Javascript
方便实用的jQuery checkbox复选框全选功能简单实例
Oct 09 Javascript
jquery获取选中的文本和值的方法
Jul 08 Javascript
在AngularJS框架中处理数据建模的方式解析
Mar 05 Javascript
jquery动态切换背景图片的简单实现方法
May 14 Javascript
javascript事件处理模型实例说明
May 31 Javascript
Vue.js组件使用开发实例教程
Nov 01 Javascript
详解jquery validate实现表单验证 (正则表达式)
Jan 18 Javascript
详解在vue-cli中使用graphql即vue-apollo的用法
Sep 08 Javascript
ionic4+angular7+cordova上传图片功能的实例代码
Jun 19 Javascript
Vue检测屏幕变化来改变不同的charts样式实例
Oct 26 Javascript
vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作
Nov 16 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生成UTF8文件的方法
2010/05/15 PHP
PHP 匿名函数与注意事项详细介绍
2016/11/26 PHP
php表单文件iframe异步上传实例讲解
2017/07/26 PHP
Jquery 1.42 checkbox 全选和反选代码
2010/03/27 Javascript
Javascript 自适应高度的Tab选项卡
2011/04/05 Javascript
document.getElementById介绍
2011/09/13 Javascript
JavaScript设置IFrame高度自适应(兼容各主流浏览器)
2013/06/05 Javascript
将两个div左右并列显示并实现点击标题切换内容
2013/10/22 Javascript
javascript查找字符串中出现最多的字符和次数的小例子
2013/10/29 Javascript
可选择和输入的下拉列表框示例
2013/11/05 Javascript
详解js闭包
2014/09/02 Javascript
jQuery的观察者模式详解
2014/12/22 Javascript
jQuery制作简洁的图片轮播效果
2015/04/03 Javascript
AngularJS  双向数据绑定详解简单实例
2016/10/20 Javascript
JS实现页面跳转参数不丢失的方法
2016/11/28 Javascript
JavaScript学习笔记之惰性函数示例详解
2017/08/27 Javascript
JavaScript实现计算圆周率到小数点后100位的方法示例
2018/05/08 Javascript
[26:52]LGD vs EG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
python Django连接MySQL数据库做增删改查
2013/11/07 Python
python 字典套字典或列表的示例
2019/12/16 Python
Python3.5 win10环境下导入kera/tensorflow报错的解决方法
2019/12/19 Python
tensorboard显示空白的解决
2020/02/15 Python
Pytorch1.5.1版本安装的方法步骤
2020/12/31 Python
Python实现疫情地图可视化
2021/02/05 Python
HTML5 UTF-8 中文乱码的解决方法
2013/11/18 HTML / CSS
美术师范毕业生自荐信
2013/11/16 职场文书
《挑山工》的教学反思
2014/02/16 职场文书
教学评估实施方案
2014/03/16 职场文书
民族团结好少年事迹材料
2014/08/19 职场文书
加入学生会自荐书
2015/03/05 职场文书
地心历险记观后感
2015/06/15 职场文书
好员工观后感
2015/06/17 职场文书
史上最全的军训拉歌口号
2015/12/25 职场文书
《工作是最好的修行》读后感3篇
2019/12/13 职场文书
mysql事务对效率的影响分析总结
2021/10/24 MySQL
MySQL七大JOIN的具体使用
2022/02/28 MySQL