今天給大家介紹一下js函數(shù)節(jié)流吧!
什么是javascript函數(shù)節(jié)流?從其字面意思可以大概猜到是一種為提升函數(shù)調(diào)用執(zhí)行性能的一種方法。javascript函數(shù)節(jié)流就是針對調(diào)用頻率高的函數(shù),通過設(shè)置定時器,使其在執(zhí)行后間隔一段時間,才進(jìn)行下一次的執(zhí)行,避免重復(fù)頻繁的調(diào)用導(dǎo)致的瀏覽器性能以及ajax重復(fù)調(diào)用問題。
函數(shù)節(jié)流的經(jīng)典應(yīng)用場景:onresize,scroll,mousemove ,mousehover等事件回調(diào)函數(shù)的無間斷執(zhí)行。其主要實現(xiàn)思路就是通過setTimeout定時器,通過設(shè)置緩沖時間,在第一次調(diào)用時,創(chuàng)建定時器,并在定時時間結(jié)束調(diào)用。第二次調(diào)用時,會清除前一個定時器并設(shè)置新的定時器。如果這時前一個定時器暫未執(zhí)行,則將其替換為新的定時器。目的在于在一定的時間內(nèi),保證多次函數(shù)的請求只執(zhí)行最后一次調(diào)用。我們看一個簡單實現(xiàn)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>函數(shù)節(jié)流</title>
<style>
body{
height: 2000px;
}
</style>
</head>
<body>
<script>
window.onscroll = function (argument) {
console.log("函數(shù)調(diào)用");
}
</script>
</body>
</html>
上面這段代碼時間線的結(jié)果在滾動頁面時,頻繁觸發(fā)了多次的函數(shù)調(diào)用,如果函數(shù)調(diào)用中涉及到了dom操作或者接口請求的話,那將是一個惡夢。
下面通過加入函數(shù)節(jié)流的方法:
<script>
window.onscroll = function(){
console.log("scroll滑動");
throttle(count);
}
function count(){
console.log("函數(shù)調(diào)用");
}
function throttle(method, context){
clearTimeout(method.tId)
method.tId = setTimeout(function(){
method.call(context);
}, 300);
}
</script>
這樣只有在停止滑動后,定時結(jié)束才執(zhí)行函數(shù)處理邏輯。
但是如果我想在滑動的時候,隔一段時間,不管有沒停止滑動,都要執(zhí)行處理邏輯,而不是像上面一樣要等到停止之后才調(diào)用,該如何實現(xiàn)呢?
var time = +new Date();
function count(){
console.log("函數(shù)調(diào)用:" + (+new Date()-time));
}
var throttle = function(fn, delay, mustRun){
var timer = null,
previous = null;
return function(){
var now = +new Date(),
context = this,
args = arguments;
if (!previous ) previous = now;
var remaining = now - previous;
if(mustRun && remaining >= mustRun){
fn.apply(context, args);
previous = now;
}else{
clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(context, args);
}, delay);
}
}
}
window.onscroll = throttle(count, 500, 1000);
這樣我們就適合于需要頻繁調(diào)用,但又在一定的時間內(nèi)必須要執(zhí)行邏輯的場景。
總結(jié): 巧用函數(shù)節(jié)流方式能夠顯著得提高頁面性能以及交互體驗,歡迎大家一起探討。