浅谈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 回车事件enter使用示例
Feb 18 Javascript
详解WordPress开发中get_current_screen()函数的使用
Jan 11 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
Jan 26 Javascript
简单实现IONIC购物车功能
Jan 10 Javascript
JavaScript函数基础详解
Feb 03 Javascript
jQuery is not defined 错误原因与解决方法小结
Mar 19 Javascript
Vue-router 类似Vuex实现组件化开发的示例
Sep 15 Javascript
HTML+JS实现“代码雨”效果源码(黑客帝国文字下落效果)
Mar 17 Javascript
JavaScript创建表格的方法
Apr 13 Javascript
vue@cli3项目模板怎么使用public目录下的静态文件
Jul 07 Javascript
几款主流好用的富文本编辑器(所见即所得常用编辑器)介绍
Mar 17 Javascript
vue递归实现树形组件
Jul 15 Vue.js
用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注入实例
2006/10/09 PHP
php无限遍历目录示例
2014/02/21 PHP
PHP Warning: Module 'modulename' already loaded in问题解决办法
2015/03/16 PHP
使用PHP similar text计算两个字符串相似度
2015/11/06 PHP
初识ThinkPHP控制器
2016/04/07 PHP
PHP静态成员变量
2017/02/14 PHP
看了就知道什么是JSON
2007/12/09 Javascript
jQuery 入门级学习笔记及源码
2010/01/22 Javascript
jQuery实现单击按钮遮罩弹出对话框(仿天猫的删除对话框)
2014/04/10 Javascript
jQuery实现购物车表单自动结算效果实例
2015/08/10 Javascript
Web程序员必备的7个JavaScript函数
2016/06/14 Javascript
BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)
2016/12/01 Javascript
简述ES6新增关键字let与var的区别
2019/08/23 Javascript
JS实现点餐自动选择框(案例分析)
2019/12/10 Javascript
js找出5个数中最大的一个数和倒数第二大的数实现方法示例小结
2020/03/04 Javascript
浅谈JavaScript窗体Window.ShowModalDialog使用
2020/07/22 Javascript
uni-app实现获取验证码倒计时功能
2020/11/01 Javascript
python3.4用循环往mysql5.7中写数据并输出的实现方法
2017/06/20 Python
Python numpy 常用函数总结
2017/12/07 Python
Python实现类似比特币的加密货币区块链的创建与交易实例
2018/03/20 Python
Centos部署django服务nginx+uwsgi的方法
2019/01/02 Python
浅谈Python 多进程默认不能共享全局变量的问题
2019/01/11 Python
详解Python3 对象组合zip()和回退方式*zip
2019/05/15 Python
python中sort和sorted排序的实例方法
2019/08/26 Python
python中查看.db文件中表格的名字及表格中的字段操作
2020/07/07 Python
解决margin 外边距合并问题
2019/07/03 HTML / CSS
css animation配合SVG制作能量流动效果
2021/03/24 HTML / CSS
费用会计岗位职责
2014/01/01 职场文书
运动会领导邀请函
2014/01/10 职场文书
温馨提示标语
2014/06/26 职场文书
企业党建工作总结2015
2015/05/26 职场文书
2016继续教育培训学习心得体会
2016/01/19 职场文书
关于Vue Router的10条高级技巧总结
2021/05/06 Vue.js
聊聊golang中多个defer的执行顺序
2021/05/08 Golang
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
2022/04/20 Python
类和原型的设计模式之复制与委托差异
2022/07/07 Javascript