防抖和节流严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。
防抖(debounce)
概念:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
场景:实时搜索(keyup)、拖拽(mousemove)
// 防抖函数
function debounce(fn, wait) {
let timer;
return function() {
let _this = this;
let args = arguments;
if(timer) { clearTimeout(timer) }
timer = setTimeout(function(){
fn.apply(_this, args)
}, wait);
}
}
// 使用
window.onresize = debounce(function() {console.log('resize')}, 500)
节流(throttle)
概念:函数的节流就是预定一个函数只有在大于等于执行周期时才会执行,周期内调用不会执行。好像一滴水只有积攒到一定重量才会落下一样。
场景:窗口调整(resize)、页面滚动(scroll)、抢购疯狂点击(movedown)
故事:阿里巴巴月饼门事件,中秋来临,阿里特意做了一个活动,抢月饼,但是每个人只能抢购一盒,有五位工程师写了js脚本,类似于12306的抢票软件,直接刷了一百多盒月饼,结果被开除了四个.其实对于他们来说并不是什么坏事,不知道有多少公司对他们敞开大门~那么如何解决这种问题呢,就用到了函数的节流
// 方式1: 使用时间戳
function throttle1(fn, wait) {
let time = 0;
return function() {
let _this = this;
let args = arguments;
let now = Date.now();
if(now - time > wait) {
fn.apply(_this, args);
time = now;
}
}
}
// 方式2: 使用定时器
function thorttle2(fn, wait) {
let timer;
return function () {
let _this = this;
let args = arguments;
if(!timer) {
timer = setTimeout(function(){
timer = null;
fn.apply(_this, args)
}, wait)
}
}
}