前言:针对一些会频繁触发的事件如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. java基础5 (一维)数组和二维数组

    本文知识点(目录): 一维数组(一维数组的概念.优点.格式.定义.初始化.遍历.常见异常.内存分析以及常见操作(找最大值.选择排序.冒泡排序等等))    二维数组(二维数组的遍历.排序.查找.定义. ...

  2. webservice常用两种身份验证方式

    在项目开发,我们经常会使用WebService,但在使用WebService时我们经常会考虑以下问题:怎么防止别人访问我的WebService?从哪里引用我的WebService?对于第一个问题,就涉 ...

  3. Centos 7 磁盘阵列配置介绍(RAID)

    转自:https://blog.51cto.com/gaowenlong/2086918 Centos 7 磁盘阵列配置介绍每当我们提到磁盘阵列,相信广大管理员并不陌生,比如我们一般安装服务器系统的时 ...

  4. javascript----数组的方法

    1---join() //1----->join()方法将数组中所有元素都转化<<字符串>> //并连接在一起 //array.join()方法是string.split ...

  5. C# WMI通过网络连接名称获取IP掩码网关

    /// <summary> /// 读取IP,掩码,网关地址 /// </summary> /// <param name="netConnectorName& ...

  6. jmeter接口/性能压测入门

    1.相关知识 https://www.cnblogs.com/star91/p/5059222.html http://www.51testing.com/zhuanti/jmeter.html 测试 ...

  7. 妙用valueForKeyPath

    valueForKey与valueForKeyPath在KVC中同时出现,都可以使用,难免让开发者迷惑:心里知道肯定是不一样,但具体的用法你会吗?其实valueForKeyPath的功能更强大,支持深 ...

  8. "做中学"之“极客时间”课程学习指导

    目录 "做中学"之"极客时间"课程学习指导 所有课程都可以选的课程 Java程序设计 移动平台开发 网络攻防实践 信息安全系统设计基础 信息安全专业导论 极客时 ...

  9. python:更改pip源

    windows更改pip源 cmd echo %APPDATA% 打开目录 创建文件夹pip 创建pip.ini文件 [global] timeout = 60 index-url = http:// ...

  10. Lesson 01-Linux安装及基础命令

    .Linux安装(略)2.基础命令 cd 切换目录 /home 切换到home目录 . 代表当前目录 .. 代表切换到当前目录的上级目录 ~ 代表切换到用户家目录 空 代表切换到用户家目录 - 代表切 ...