前言:针对一些会频繁触发的事件如scroll、resize,如果正常绑定事件处理函数的话,有可能在很短的时间内多次连续触发事件,十分影响性能

节流:

节流:使得一定时间内只触发一次函数。
它和防抖动最大的区别就是,节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而防抖动只是在最后一次事件后才触发一次函数。
原理是通过判断是否到达一定时间来触发函数,若没到规定时间则使用计时器延后,而下一次事件则会重新设定计时器

主要有两种实现方法:

  • 时间戳
  • 定时器

时间戳实现:当高频事件触发时,第一次应该会立即执行(给事件绑定函数与真正触发事件的间隔如果大于delay的话),而后再怎么频繁触发事件,也都是会每delay秒才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了。

var throttle = function(func,delay){
var prev = Date.now();
return function(){
var context = this;
var args = arguments;
var now = Date.now();
if(now-prev>=delay){
func.apply(context,args);
prev = Date.now();
}
}
}

定时器实现: 当触发事件的时候,我们设置一个定时器,再触发事件的时候,如果定时器存在,就不执行;直到delay秒后,定时器执行执行函数,清空定时器,这样就可以设置下个定时器。

var throttle = fucntion(func,delay){
var timer = null; return funtion(){
var context = this;
var args = arguments;
if(!timer){
timer = setTimeout(function(){
func.apply(context,args);
timer = null;
},delay);
}
}
}

当第一次触发事件时,肯定不会立即执行函数,而是在delay秒后才执行。 
之后连续不断触发事件,也会每delay秒执行一次。 
当最后一次停止触发后,由于定时器的delay延迟,可能还会执行一次函数。

综合使用时间戳与定时器,完成一个事件触发时立即执行,触发完毕还能执行一次的节流函数:

var throttle = function(func,delay){
var timer = null;
var startTime = Date.now(); return function(){
var curTime = Date.now();
var remaining = delay-(curTime-startTime);
var context = this;
var args = arguments; clearTimeout(timer);
if(remaining<=){
func.apply(context,args);
startTime = Date.now();
}else{
timer = setTimeout(func,remaining);
}
}
}

防抖动:

防抖动:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发

// 将会包装事件的 debounce 函数
function debounce(fn, delay) {
// 维护一个 timer
let timer = null; return function() {
// 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
let context = this;
let args = arguments; clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
}
}

1. 首先,我们为scroll事件绑定处理函数,这时debounce函数会立即调用,
 因此给scroll事件绑定的函数实际上是debounce内部返回的函数

2. 每一次事件被触发,都会清除当前的 timer 然后重新设置超时调用。
    这就会导致每一次高频事件都会取消前一次的超时调用,导致事件处理程序不能被触发

3. 只有当高频事件停止,最后一次事件触发的超时调用才能在delay时间后执行

写在最后: 节流和防抖运用场景还是蛮多的,也是最为性能优化的一大利器;欢迎指正不足之处

js前端性能优化之函数节流和函数防抖的更多相关文章

  1. [js] 前端性能优化

    原文链接:http://www.cnblogs.com/xxcanghai/p/5205998.html 链接:http://www.zhihu.com/question/21658448/answe ...

  2. Js基础知识(五) - 前端性能优化总结

    前端性能优化总结 资源优化 缓存 最好的资源优化就是不加载资源.缓存也是最见效的优化手段.说实话,虽然说客户端缓存发生在浏览器端,但缓存主要还是服务端来控制,与我们前端关系并不是很大.但还是有必要了解 ...

  3. Web前端性能优化教程07:精简JS 移除重复脚本

    本文是Web前端性能优化系列文章中的第七篇,主要讲述内容:精简Javascript代码,以及移出重复脚本.完整教程可查看:  一.精简javascript 基础知识 精简:从javascript代码中 ...

  4. WEB前端性能优化:HTML,CSS,JS和服务器端优化

    对前端开发工程师来说,前端性能优化的重要性是不言而喻的,最为大家所知的是YSLOW的23条优化规则,在我的理解中,性能优化不纯粹是指用户访问网站的速度,也包括开发的效率,这里我总结下我理解中的WEB前 ...

  5. 前端性能优化之Lazyload

    前端性能优化之Lazyload @(Mob前端-冬晨)[JavaScript|技术分享|懒加载] [TOC] Lazyload 简介 前端工作中,界面和效果正在变得越来越狂拽炫酷,与此同时性能也是不得 ...

  6. Web前端性能优化,应该怎么做?

    摘要:本文将分享一些前端性能优化的常用手段,包括减少请求次数.减小资源大小.各种缓存.预处理和长连接机制,以及代码方面的性能优化等方面. base64:尤其是在移动端,小图标可以base64(webp ...

  7. Web前端性能优化教程05:网站样式和脚本

    本文是Web前端性能优化系列文章中的第五篇,主要讲述内容:网站样式和脚本代码的放置位置.使用外部javascript和css.完整教程可查看:Web前端性能优化 一.将样式表放在顶部 可视性回馈的重要 ...

  8. JS 之性能优化(2)

    继续上一篇的JS性能优化之后,下面接着讲关于前端性能优化的内容.如果有不对的地方欢迎纠正. 1.避免过多的重排与重绘操作. 尽量将DOM中的多个读操作放一起,中间不要插入写的操作,因为写操作会导致浏览 ...

  9. Web前端性能优化——如何提高页面加载速度

    前言:  在同样的网络环境下,两个同样能满足你的需求的网站,一个"Duang"的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒, ...

随机推荐

  1. Centos7 pcs pacemaker高可用安装配置详解

  2. Linux基础命令---iostat显示设备状态

    iostat iostat指令用来显示cpu状态,系统IO设备的状态,以及相关磁盘和NFS使用状态.iostat命令通过观察设备相对于其平均传输速率的活动时间来监视系统输入/输出设备负载.iostat ...

  3. Windows Server 2008安装IIS 7与配置

    一.安装IIS 7 1.鼠标右键[我的电脑(Computer)]→[管理(Manager)] 2.选择[角色(Roles)],右键[添加角色(Add Roles)],弹出[添加角色向导(Add Rol ...

  4. pandas替换一列中的汉字为数字

    表格的一列“总金额”应该全部为数字,但其中少数项出现汉字,应该将汉字替换为数字,才能进行后面的计算. 先定义一个函数: def is_number(s): try: float(s) return T ...

  5. 关于Java多线程的一些常考知识点

    前言 Java多线程也是面试中经常会提起到的一个点.面试官会问:实现多线程的两种方式以及区别,死锁发生的4个条件以及如何避免发生死锁,死锁和活锁的区别,常见的线程池以及区别,怎么理解有界队列与无界队列 ...

  6. Java基础实训2

    1. 一维数组的创建和遍历. 声明并创建存放4个人考试成绩的一维数组,并使用for循环遍历数组并打印分数.要求: (1)    首先按“顺序”遍历,即打印顺序为:从第一个人到第四个人: (2)    ...

  7. 软件测试2gkd

    JUnit单元测试 一.单元测试的概念和目的 什么是单元测试?单元测试是在开发过程中要进行的最低级别的测试活动,是需要与开发同步进行的工作,它由程序员自己完成,属于编码的一部分.单元测试是为了确保类的 ...

  8. topcoder srm 630 div1 (2-SAT and SCC template)

    problem1 link 首先计算任意两点的距离.然后枚举选出的集合中的两个点,判断其他点是否可以即可. problem2 link 假设字符串为$s$,长度为$n$.那么对于$SA$中的两个排名$ ...

  9. pycharm 序列号/行号 的宽度太宽了如何调整

    问题:行号宽度嫌宽: 解决:在settings里面,如下图顺序,取消“show gutter icons”的勾,即可. 调整后如下图:

  10. Manjaro搭建无密访问samba服务器

    为了方便Linux在Windows平台下开发,搭建Manjaro无密访问samba服务器 后面加了Windows下搭建samba方法 安装smb服务器 我用的是Manjaro gnome 18,需要安 ...