一、防抖(debounce)
某一操作在規(guī)定時(shí)間內(nèi)再未觸發(fā),則執(zhí)行回調(diào),若觸發(fā),則重新計(jì)時(shí)。
let start = +new Date();
//聲明一個(gè)柯里化函數(shù)
function debounce(fun, delay){
return function(args){
let that = this;
//執(zhí)行該語(yǔ)句時(shí)若距離上次執(zhí)行時(shí)間未超過(guò)delay毫秒,則在定時(shí)器執(zhí)行前清除該
//定時(shí)器,并啟用新的定時(shí)器
//反之超過(guò)delay毫秒,定時(shí)器ID(fun.id)對(duì)應(yīng)的定時(shí)器已執(zhí)行
clearTimeout(fun.id);
fun.id = setTimeout(function(){ //delay時(shí)長(zhǎng)后,執(zhí)行定時(shí)器
fun.call(that, args)
},delay)
}
}
let con = function(){
console.log(+new Date - start);
}
let highFun = debounce(con, 1000);
setInterval(highFun, 300); //沒(méi)有打印
setInterval(highFun, 3000); //第一次4s后打印,之后每隔3s打印
應(yīng)用場(chǎng)景:
1、用戶(hù)輸入觸發(fā)請(qǐng)求發(fā)送或者窗口更新時(shí),應(yīng)用debounce減少請(qǐng)求和更新頻率。
二、節(jié)流(debounce)
規(guī)定時(shí)間內(nèi)只觸發(fā)一次,該時(shí)間內(nèi)的其余觸發(fā)無(wú)效。
let start = +new Date();
let con = function(){
console.log(+new Date - start);
}
function throttle(fn, delay){
let last, stid;
return function(args){
let that = this;
let time = +new Date();
//如果第一次執(zhí)行或者距離上次執(zhí)行超過(guò)delay,則執(zhí)行下一次操作
if(!last || time - last > delay){
last = time;
fn.apply(that, args)
}
}
}
//每10ms嘗試執(zhí)行打印操作,實(shí)際每約1s執(zhí)行一次
setInterval(throttle(con, 1000), 10);
應(yīng)用場(chǎng)景:
1、canvas動(dòng)畫(huà)中,結(jié)合requestAnimationFrame來(lái)控制人物每秒移動(dòng)的距離
2、發(fā)送請(qǐng)求時(shí),在回調(diào)成功前阻止請(qǐng)求多次發(fā)送
3、窗口的scroll事件中,滑動(dòng)一定時(shí)間或距離后執(zhí)行自定義操作
三、分時(shí)函數(shù)
當(dāng)遇到一次性大量渲染時(shí),嘗試將大任務(wù)分割成小任務(wù)延時(shí)完成。
// arr: 源數(shù)據(jù)
// process: 處理函數(shù)
// count: 每次抽取個(gè)數(shù)
var chunk = function(arr, process, count){
setTimeout(function(){
for(var i = 0, len = Math.min(count, arr.length); i < len; i++) {
//取出數(shù)組中的第一個(gè)數(shù)據(jù)進(jìn)行處理,并在源數(shù)據(jù)中刪除
process(arr.shift());
}
if(arr.length > 0) {
//若有剩余任務(wù),則100ms后調(diào)用自身繼續(xù)處理
setTimeout(arguments.callee, 100);
}
}, 100);
}
應(yīng)用場(chǎng)景:
1、處理大量DOM渲染時(shí),分割成小任務(wù)以減輕瀏覽器壓力。
四、總結(jié):
防抖節(jié)流以及分時(shí)函數(shù)的本質(zhì)都是限制函數(shù)的高頻觸發(fā)來(lái)提高頁(yè)面性能。
參考文章:
https://juejin.im/post/5b8de829f265da43623c4261
https://juejin.im/entry/5815876c8ac247004fb6d132/