浅谈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和Mozilla的兼容性汇总event
Aug 12 Javascript
Javascript表格翻页效果的具体实现
Oct 05 Javascript
JS 日期比较大小的简单实例
Jan 13 Javascript
js中数组(Array)的排序(sort)注意事项说明
Jan 24 Javascript
js实现消息滚动效果
Jan 18 Javascript
vuex state及mapState的基础用法详解
Apr 19 Javascript
微信小程序制作表格的方法
Feb 14 Javascript
Vue组件系列开发之模态框
Apr 18 Javascript
深入了解JavaScript 的 WebAssembly
Jun 15 Javascript
jquery实现吸顶导航效果
Jan 08 jQuery
详解微信小程序中var、let、const用法与区别
Jan 11 Javascript
vue video和vue-video-player实现视频铺满教程
Oct 30 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/04/21 PHP
php Ubb代码编辑器函数代码
2012/07/05 PHP
php使用function_exists判断函数可用的方法
2014/11/19 PHP
js 遍历对象的属性的代码
2011/12/29 Javascript
js去除重复字符串两种实现方法
2013/01/09 Javascript
Javascript基础知识盲点总结之函数
2016/05/15 Javascript
JS实现放大、缩小及拖拽图片的方法【可兼容IE、火狐】
2016/08/23 Javascript
浅谈html转义及防止javascript注入攻击的方法
2016/12/04 Javascript
基于jQuery实现咖啡订单管理简单应用
2017/02/10 Javascript
jquery中each循环的简单回滚操作
2017/05/05 jQuery
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
详解JavaScript实现动态的轮播图效果
2019/04/29 Javascript
ES6顶层对象、global对象实例分析
2019/06/14 Javascript
laypage.js分页插件使用方法详解
2019/07/27 Javascript
vue中实现动态生成二维码的方法
2020/02/21 Javascript
nuxt 自定义 auth 中间件实现令牌的持久化操作
2020/11/05 Javascript
[02:14]完美“圣”典2016风云人物:xiao8专访
2016/12/01 DOTA
[02:22]《新闻直播间》2017年08月14日
2017/08/15 DOTA
Python实现抓取页面上链接的简单爬虫分享
2015/01/21 Python
python 3.5实现检测路由器流量并写入txt的方法实例
2017/12/17 Python
python生成不重复随机数和对list乱序的解决方法
2018/04/09 Python
Python2 Selenium元素定位的实现(8种)
2019/02/25 Python
Django框架中间件(Middleware)用法实例分析
2019/05/24 Python
浅谈python3中input输入的使用
2019/08/02 Python
Python3实现打印任意宽度的菱形代码
2020/04/12 Python
浅谈Python3中print函数的换行
2020/08/05 Python
CSS3实现可翻转的hover效果
2018/05/23 HTML / CSS
详解HTML5中垂直上下居中的解决方案
2017/12/20 HTML / CSS
Hotels.com拉丁美洲:从豪华酒店到经济型酒店的预定优惠和折扣
2019/12/09 全球购物
尊老爱亲美德少年事迹材料
2014/08/14 职场文书
2015元旦标语横幅
2014/12/09 职场文书
五年级学生评语大全
2014/12/26 职场文书
人间正道是沧桑观后感
2015/06/15 职场文书
苦儿流浪记读书笔记
2015/07/01 职场文书
新员工入职感想
2015/08/07 职场文书
使用Pytorch训练two-head网络的操作
2021/05/28 Python