函數(shù)的節(jié)流

今天小馬哥讓優(yōu)化代碼,當(dāng)input 框輸入數(shù)字時(shí),會(huì)觸發(fā)一系列的運(yùn)算及邏輯處理,watch 監(jiān)控輸入變化,當(dāng)input的value 有改變時(shí),則會(huì)瘋狂請(qǐng)求處理運(yùn)算的接口,這樣一來(lái),這種處理方式則可能增加瀏覽器重繪和回流次數(shù),進(jìn)而增加了瀏覽器的負(fù)擔(dān),服務(wù)器也很疲憊,一開(kāi)始我只是很膚淺的找代碼中接口的調(diào)用次數(shù),位置,以及網(wǎng)絡(luò)請(qǐng)求多次的問(wèn)題。然而,事情并不是這么簡(jiǎn)單,所以,今天我在這里分享一下,關(guān)于節(jié)流的問(wèn)題。

1.首先我可能不會(huì)直入主題,女孩子一般喜歡拐彎抹角的說(shuō)一個(gè)問(wèn)題,我總覺(jué)得懂得拐彎肯定會(huì)多收獲不少的風(fēng)景。不羅嗦了,先講一個(gè)常見(jiàn)的通過(guò)雙向綁定來(lái)實(shí)現(xiàn)的搜索功能。
我直接貼代碼了。

<input type="text" id="search" name = "search"/>
<p id='textId'></p>

<script>
var input = document.getElementById('search');
var textId = document.getElementById('textId');
function queryData(text){
console.log(text,'text');
textId.innerHTML =text;
}

input.addEventListener('keyup',function(event){
    console.log(event,'event');
    queryData(this.value);
})

</script>

這段代碼瀏覽器執(zhí)行的結(jié)果是這樣的:


image.png

不要介意我的突然表白,這些都不重要,重要的是,你發(fā)現(xiàn)沒(méi)有,這就是一個(gè)典型的雙向數(shù)據(jù)綁定的原生實(shí)現(xiàn)。嘿嘿,不慌,問(wèn)題來(lái)了,你會(huì)發(fā)現(xiàn),我沒(méi)輸入一個(gè)字符的時(shí)候,都會(huì)掉一次queryData這個(gè)方法,這可能不是我特別想要的,我覺(jué)得有點(diǎn)繁瑣,我想無(wú)論我打多少個(gè)字符,在特定的時(shí)間內(nèi),只需要給我輸出一到兩個(gè)就好,否則的話在每次改變input value 值時(shí)瀏覽器可能都會(huì)發(fā)生重繪,性能肯定是不行的,為了優(yōu)化性能,我能開(kāi)始進(jìn)行第2個(gè)問(wèn)題的講解。
2.節(jié)流函數(shù)的實(shí)現(xiàn)原理。
上代碼:
// 使用節(jié)流的情況
var input = document.getElementById('search');
var textId = document.getElementById('textId');
function queryData(text){
textId.innerHTML = text;
}

input.addEventListener('keyup',function(event){
    throttle(queryData,null,500,this.value);
})
function throttle(fn,context,delay,text){
    clearTimeout(fn.timeoutId);
    fn.timeoutId = setTimeout(function(){
        fn.call(context,text);
    },delay);
}

說(shuō)明:li'yong'd'n
這段代碼瀏覽器執(zhí)行的結(jié)果是這樣的:


image.png

由運(yùn)行結(jié)果可以看出,節(jié)流就是我們通過(guò)在特定的時(shí)間段內(nèi),來(lái)控制調(diào)用函數(shù)的次數(shù),進(jìn)而減少瀏覽器的重繪與回流。這只是個(gè)比較基礎(chǔ)的,原理性的實(shí)現(xiàn)函數(shù)節(jié)流的一種方案,那么如果我們像繼續(xù)優(yōu)化,請(qǐng)看第3部分的講解。

3.到一定時(shí)間間隔之后,queryData函數(shù)必然會(huì)被調(diào)用,但是又不是頻繁的調(diào)用。這既達(dá)到了節(jié)流的目的,又不會(huì)影響用戶體驗(yàn)。
上代碼:
// 使用節(jié)流的情況
var input = document.getElementById('search');
var textId = document.getElementById('textId');
function queryData(text){
textId.innerHTML = text;
console.log(text,'text');
}

input.addEventListener('keyup',function(event){
    throttle(queryData,null,600,this.value);
})
function throttle(fn,context,delay,text,centerTime){
    clearTimeout(fn.timeoutId);
    fn.currentTime = new Date();
    if(!fn.startTime){
        fn.startTime = fn.currentTime;
    }

    if(fn.currentTime - fn.startTime > centerTime){
       fn.call(context,text);
       fn.startTime = fn.currentTime;
    }else{
         fn.timeoutId = setTimeout(function(){
                fn.call(context,text);
            },delay);
    } 
}

我來(lái)講解一下:加了一個(gè)時(shí)間間隔的比較,如果在那個(gè)時(shí)間間隔內(nèi)觸發(fā)input 框里的東西,


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容