防抖和節(jié)流

防抖(Debounce)和節(jié)流(throttle)都是用來控制某個函數(shù)在一定時間內(nèi)執(zhí)行多少次的技巧,兩者相似而又不同。

函數(shù)節(jié)流(throttle):是讓一個函數(shù)無法在很短的時間間隔內(nèi)連續(xù)調(diào)用,當(dāng)上一次函數(shù)執(zhí)行后過了規(guī)定的時間間隔,才能進(jìn)行下一次該函數(shù)的調(diào)用。
函數(shù)去抖(debounce):讓一個函數(shù)在一定間隔內(nèi)沒有被調(diào)用時,才開始執(zhí)行被調(diào)用方法。
兩個方法都是用來提升前端性能,減輕瀏覽器壓力。

防抖:

我們拿最為常見的scroll事件做例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        div{
            height: 3000px;
        }
    </style>
</head>
<body>
<div>
</div>
<script>
    window.onload=function () {
        window.onscroll=function () {
            console.log(document.body.scrollTop || document.documentElement.scrollTop);
        }
    }
</script>
</body>
</html>

未作防抖處理之前,我們看看會發(fā)生什么


1.gif

我們滾動鼠標(biāo)滾輪,短時間內(nèi)觸發(fā)多個事件,DOM操作是很耗費(fèi)性能的,如果在監(jiān)聽中,做了一些DOM操作,那無疑會給瀏覽器造成大量性能損失。
進(jìn)行處理后的代碼如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        div{
            height: 3000px;
        }
    </style>
</head>
<body>
<div>
</div>
<script>
    window.onload=function () {
        let timer;
        window.onscroll=function () {
            if(timer){
                clearTimeout(timer);
            }
            timer=setTimeout(function () {
                console.log(document.body.scrollTop || document.documentElement.scrollTop);
            },200);
        }
    }
</script>
</body>
</html>

防抖效果如下


2.gif

對防抖函數(shù)進(jìn)行封裝

/**
     *防抖函數(shù)封裝
     *@method debounce
     *@param {function|element}method
     *@param {number|element}delay
     *@return {function|element}
     */
    function debounce(method,delay){
        let timer;
        return function () {
            if (timer){
                clearTimeout(timer);
            }
            timer=setTimeout(function () {
                let params=Array.prototype.slice.apply(arguments);
                method.apply(this,params);
            },delay)
        }
    }
   window.onscroll=debounce(function () {
       console.log(document.body.scrollTop || document.documentElement.scrollTop);
   },200);

我認(rèn)為防抖效果應(yīng)該會應(yīng)用在電商平臺訂單提交之中,不可能讓用戶瘋狂點(diǎn)擊提交訂單。

節(jié)流:我們拿點(diǎn)擊事件做例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button>
    點(diǎn)擊
</button>
<script>
   let btn=document.getElementsByTagName("button")[0];
   btn.onclick=function () {
       console.log(1);
   }
</script>
</body>
</html>

未進(jìn)行節(jié)流處理


3.gif

進(jìn)行節(jié)流處理后

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button>
    點(diǎn)擊
</button>
<script>
   let btn=document.getElementsByTagName("button")[0];
   let flag=true;
   btn.onclick=function () {
       if (flag){
           console.log(1);
           flag=false;
           setTimeout(function () {
               flag=true;
           },2000);
       } 
   }
</script>
</body>
</html>

效果如下


4.gif

對節(jié)流函數(shù)進(jìn)行封裝

/**
     * throttle
     * @param method
     * @param delay
     * @return {Function}
     */
    let flag=true;
    function throttle(method,delay){
        return function () {
            if (flag){
                let params=Array.prototype.slice.apply(arguments);
                method.apply(this,params);
                flag=false;
                setTimeout(function () {
                    flag=true;
                },delay)
            }
        }
    }

節(jié)流函數(shù)的使用還是很常見的,比如無縫輪播圖的換頁點(diǎn)擊,不能讓用戶一直點(diǎn)擊按鍵,至少應(yīng)當(dāng)?shù)却隧摲撏瓿伞?br> ps:最近用支付寶里面的餓了么點(diǎn)外賣,由于等了很久沒來,連續(xù)多次點(diǎn)了催單按鈕,然后“奇怪”的事情就發(fā)生了,我停止點(diǎn)擊后,每隔一秒就出現(xiàn)已催單的提示,就這樣持續(xù)了接近半分鐘,我感覺這個現(xiàn)象應(yīng)該和防抖和節(jié)流有關(guān)。

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

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

  • 其實(shí)早就聽說了節(jié)流和防抖的解決方案。這兩個的目的都是為了提升頁面中監(jiān)聽事件的性能。才疏學(xué)淺,如果有錯誤,也希望各位...
    Katherine的小世界閱讀 1,968評論 0 6
  • 在前端開發(fā)過程中,我們經(jīng)常需要綁定一些持續(xù)觸發(fā)事件,如:resize、scroll、mousemove等等,但有些...
    廊橋夢醉閱讀 6,147評論 0 40
  • (函數(shù)防抖和節(jié)流是什么意思?分別用于什么情況下) http://www.jb51.net/article/1056...
    blueblue_c41a閱讀 866評論 0 2
  • 一、問題 如何解決用戶頻繁操作所帶來的性能問題? 二、場景 簡書中的Markdown預(yù)覽功能,希望用戶停止輸入0....
    Eric_lwh閱讀 466評論 0 0
  • 在前端開發(fā)的過程中,我們經(jīng)常會需要綁定一些持續(xù)觸發(fā)的事件,如 resize、scroll、mousemove 等等...
    淘淘笙悅閱讀 227,223評論 42 349

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