这周公司对其项目要进行一些性能优化,所以记录一下
防抖(Debounce)和节流(Throttle)都是用来控制某个函数在一定时间内执行多少次的技巧,
针对于公司的这个项目,我顺便解释下它们之间的区别:
防抖:
比如在加入购物车的时候,后端服务器卡了一下,你连续点击了2次,两条都过去了,后端的数据来不及生成,导致两条一样的数据在数据库
(前端传过来的id,后端要先根据id去进行find操作,要是没有这个数据就create一条,要是有的话就update一下数量。
如果服务器卡了一下的话,连续2次点击,第一条都来不及反应,就都会执行created操作,就创建了2条数据,
其实实际要是一开始没有的话只需要创建1条,再有的话就update下条数就行了)
节流:
比如在秒杀的时候,一下会点击好多次,这样会给服务器端造成很大的压力,就会设定你点一次之后,再点击是不生效的,下次要等1s之后点击才会执行
方法一:
防抖(Debounce)
在函数被触发n秒后再执行,如果在n秒内又有函数执行,则重新计算。
我们在做搜索功能的时候,如果每输入一个字符就调用一次接口,会导致请求过于频繁。
但这些请求中,只有最后一个请求是有意义的,因为最后一个请求发出时,我们已经输入了完整的搜索词,
而前面没有意义的请求,是对网络资源的浪费。此时就可以使用debounce,把触发非常频繁的事件合并成一次执行。
实现思路
/**
* @fn : 要执行的函数
* @delay : 执行函数的时间间隔
*/
function debounce(fn,delay){
let timer; // 定时器
return function(...args){ // 形成闭包
// args 为函数调用时传的参数。
let context = this;
timer&&clearTimeout(timer); // 当函数再次执行时,清除定时器,重新开始计时
// 利用定时器,让指定函数延迟执行。
timer = setTimeout(function(){
// 执行传入的指定函数,利用apply更改this绑定和传参
fn.apply(context,args);
},delay)
}
}
使用
debounce(doSomething,200);
节流(Throttle)
允许一个函数在 X 毫秒内只执行一次。
当你需要监听滚动条变化,从而去计算页面中某个元素到窗口顶部距离的时候。
可以使用Throttle,不用实时去计算元素的位置,而是一段时间计算一次,可以避免频繁执行代码,防止浏览器频繁响应事件,严重拉低性能。
/**
* @fn : 要执行的函数
* @delay : 每次函数的时间间隔
*/
function throttle(fn,delay){
let timer; // 定时器
return function(...args){
let context = this;
// 如果timer存在,说明函数还未该执行
if(timer) return;
timer = setTimeout(function(...args){
// 当函数执行时,让timer为null。
timer = null;
fn.apply(context,args);
},delay);
}
}
使用
throttle(doSomething,200);
方法二:
使用Lodash插件
Lodash是一个javascript 工具库,它内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数。
可以直接使用 Lodash 的自定义构建工具,调用_.debounce 和_.throttle 方法。
1、安装插件:
npm i --save lodash
2、在要用到防抖节流的页面引入:
import _ from 'lodash'
3、写入:
_.debounce(doSomething, 200);
_.throttle (doSomething, 200);