[概念] js的函数节流和throttle和debounce详解
js的函数节流和throttle和debounce详解:
同样是实现了一个功能,可能有的效率高,有的效率低,这种现象在高耗能的执行过程中区分就比较明显。
本章节一个比较常用的提高性能的方式,通常叫做"函数节流",下面就通过代码实例对此做一下介绍。
一.函数节流是什么:
在实际编码中,mousemove和resize是使用非常频繁的事件类型(当然还有其他类似事件类型),这样的事件有一个共同的特点,就是在一个普通的操作中,就有可能会在极短的时间内多次执行事件处理函数,会极大的损耗性能,比如resize事件,每次执行通常都会对dom元素进行重新计算,这是非常损耗性能的,何况是频繁的执行,所以在不影响效果的情况下尽可能的减少事件处理函数的执行次数是非常重要的。
二.函数节流的方式:
1.throttle方式:
此单词英文就有"节流"的意思。
更通俗的说就是调节函数执行的频率,控制函数连续两次执行的时间间隔。
下面一个代码:
|
1
2
3
4
5
6
7
8
9
|
var timer=null;$(window).on('resize',function(){ if(timer){ clearTimeout(timer) } timer=setTimeout(function(){ console.log("蚂蚁部落"); },400);}); |
代码实现了函数节流效果,当调整浏览器窗口大小的时候,"蚂蚁部落"就不会被输出,当调整停止后的400毫秒后才会输出。
上面的方式的的确确实现了函数节流效果,但是感觉有点太狠了,通常我们需要的不是当调整的时候不会输出,而是输出的频率低一点,实现这样的功能,后面会分享一段代码。
2.debounce方式:
此方式和throttle类似,但是它的关注点是函数调用的时间间隔,throttle的关注点是函数执行的时间间隔。
debounce方式对于控制长按键盘暴力输入这种现象非常有效。
三.实例代码:
如果相对函数节流彻底理解掌握,最好完整的分析一段实现此功能的源码。
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
var throttle = function (fn,delay, immediate, debounce) { var curr = +new Date(), last_call = 0, last_exec = 0, timer = null, diff, context, args, exec = function () { last_exec = curr; fn.apply(context, args); }; return function () { curr= +new Date(); context = this, args = arguments, diff = curr - (debounce ? last_call : last_exec) - delay; clearTimeout(timer); if(debounce){ if(!immediate){ timer=setTimeout(exec, delay); } else if(diff >= 0){ exec(); } } else{ if(diff >= 0){ exec(); } else if(!immediate){ timer = setTimeout(exec, -diff); } } last_call = curr; }}; |
代码虽然将函数对象引用赋值给名为throttle的变量,其实它实现throttle和debounce两种方式,只要调整一下参数即可,下面就对它的实现过程做一下注释。
代码注释:
1.var throttle = function (fn,delay, immediate, debounce) {},此函数能够返回一个可以作为事件处理函数,具有四个参数,fn是一个函数对象,被节流的就是它的执行,delay规定延迟执行的时间,单位是毫秒,immediate是一个布尔值,如果是true,那么相关函数就会立即执行,否则延迟执行,debounce是个布尔值,如果是true,那么就是采用debounce方式。
2.var curr = +new Date(),获取当前时间,是一个时间戳。
3.last_call = 0,声明一个变量并初始化为0,它用来存储上一次试图调用函数的时间。
4.last_exec = 0,声明一个变量并初始化为0,它用来存储上一次函数函数执行的时间。
5.timer = null,声明一个变量,并初始化null,它会存储定时器函数的标识。
6.diff,用来存储时间差。
7.context,用来存储一个上下文对象。
8.args,用来存储函数的参数。
9.exec = function () {
last_exec = curr;
fn.apply(context, args);
};声明一个函数,此函数可以获取函数执行的事件,并且执行通过参数传递过来的fn函数。
10.return function () {},返回一个函数,被返回的这个函数就是不断被调用的事件处理函数。
11.curr= +new Date(),获取当前时间对象的时间戳。
12.context = this,将context赋值为this。
13.args = arguments,将参数对象集合赋值给变量args。
14.diff = curr - (debounce ? last_call : last_exec) - delay,这一个很有技巧,可以获取当前时间与延迟时间和上一次被调用的时间或者执行时间的时间差。
15. clearTimeout(timer),停止定时器函数的执行。
16.if(debounce){ if(!immediate){
timer=setTimeout(exec, delay);
}
else if(diff >= 0){
exec();
}
}
如果采用debounce方式,并且采用延迟方式,那么函数会延迟指定的时间再去执行,如果没有采用延迟方式,并且时间差大于等于0(说明延迟时间已到),就执行函数。
17.else{
if(diff >= 0){
exec();
}
else if(!immediate){
timer = setTimeout(exec, -diff);
}
}
如果采用的是throttle方式,那么就会判断diff 是否大于0,如果大于0就执行函数,第一次执行的时候肯定会大于0,也就是说throttle方式在第一次执行的时候不会有延迟效果。如果不大于零,且采用延迟模式的话,就会延迟执行。
也许看了上面的介绍,对两种方式感觉比较混乱,那么可以参阅函数节流throttle和debounce代码演示一章节,这样就可以比较直观的观察两者的作用和相互间的区别了。
[概念] js的函数节流和throttle和debounce详解的更多相关文章
- JS的函数节流(throttle)
什么是函数节流? 介绍前,先说下背景.在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(其核心就是绑定mousemove),这种事件有一个特点,就是用户不必特地捣乱,他在 ...
- (转)JavaScript-性能优化之函数节流(throttle)与函数去抖(debounce)
JavaScript-性能优化之函数节流(throttle)与函数去抖(debounce) 函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过 ...
- 函数防抖(Debounce)、函数节流 (Throttle)
一篇介绍文章:https://zhuanlan.zhihu.com/p/38313717 演示示例:http://demo.nimius.net/debounce_throttle/ 函数防抖(Deb ...
- js实现的新闻列表垂直滚动实现详解
js实现的新闻列表垂直滚动实现详解:新闻列表垂直滚动效果在大量的网站都有应用,有点自然是不言而喻的,首先由于网页的空间有限,使用滚动代码可以使用最小的空间提供更多的信息量,还有让网页有了动态的效果,更 ...
- str_replace函数的使用规则和案例详解
str_replace函数的使用规则和案例详解 str_replace函数的简单调用: <?php $str = '苹果很好吃.'; //请将变量$str中的苹果替换成香蕉 $strg = st ...
- main.js index.html与app.vue三者关系详解
main.js index.html与app.vue三者关系详解 2019年01月23日 11:12:15 Pecodo 阅读数 186 main.js与index.html是nodejs的项目启 ...
- js 高程 函数节流 throttle() 分析与优化
在 js 高程 22.3.3章节 里看到了 函数节流 的概念,觉得给出的代码可以优化,并且概念理解可以清晰些,所以总结如下: 先看 函数节流 的定义,书上原话(斜体表示): 产生原因/适用场景: 浏览 ...
- JS魔法堂:函数节流(throttle)与函数去抖(debounce)
一.前言 以下场景往往由于事件频繁被触发,因而频繁执行DOM操作.资源加载等重行为,导致UI停顿甚至浏览器崩溃. 1. window对象的resize.scroll事件 2. 拖拽时的mousemov ...
- JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)
函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用. 函数节流的原理挺简单的,估计大家都想到了,那就是定时器.当我 ...
随机推荐
- C语言深度剖析---预处理(define)(转载)
1.数值宏常量 #define宏定义是个演技非常高超的替身演员,但也会耍大牌的,所以我们使用它要慎之又慎.它可以出现在代码的任何地方,从本行宏定义开始,以后的代码都认识宏了:也可以把任何东西都 ...
- POJ1054 枚举【STL__binary_search()_的应用】
①使用binary_search前要先保证有序 ②binary_search函数仅返回true或false ③binary_search(first element, laste lment + 1, ...
- CMAKE的使用
CMAKE的使用 Version 1.0 2009-3-18 一. 基本使用 安装:下载二进制包后可直接解压使用 从源码安装则执行命令:./bootstrap; make; make ins ...
- 给centOs添加epel源
epel简介: https://fedoraproject.org/wiki/EPEL/zh-cn 1. rpm -Uvh http://dl.fedoraproject.org/pub/epel/5 ...
- aliyun 主机Nginx 上配置Drupal 伪静态
网上找了好久没有正确的,后面直接在http://wiki.nginx.org/Drupal 上找到原文.但原文中复制过来会出现个 'root' rewrite directive is duplica ...
- SDCard助手类
package com.zyh.sdcardHelper; import java.io.BufferedInputStream; import java.io.BufferedOutputStrea ...
- 解决win7 中source insight没有courier new字节的问题
解决win7 中source insight没有courier new字节的问题 http://blog.csdn.net/season_hangzhou/article/details/18665 ...
- 一天一个类,一点也不累之TreeSet
一天一个类,一点也不累. 现在要说的是---TreeSet public class TreeSet<E> extends AbstractSet<E> implements ...
- java--join方法
package MyTest; class TestDemo implements Runnable { public void run() { int i = 0; for (int j = 0; ...
- 【转】android加载大量图片内存溢出的三种解决办法
方法一: 在从网络或本地加载图片的时候,只加载缩略图. /** * 按照路径加载图片 * @param path 图片资源的存放路径 * @param scalSize 缩小的倍数 * @return ...