函數(shù)節(jié)流和防抖

前言

瀏覽器中某些計算和處理要比其他的昂貴很多。例如DOM操作比DOM交互需要更多的時間和cpu時間,為了提升性能呕屎,減少DOM操作,于是敬察,函數(shù)節(jié)流防抖和應(yīng)運而生秀睛,其函數(shù)節(jié)流的基本思想是指莲祸,某些代碼不可以在沒有間斷的情況下連續(xù)重復(fù)執(zhí)行锐帜。函數(shù)防抖的基本思想是指,一個頻繁觸發(fā)的事情只讓最后一次執(zhí)行瓷式。下面就讓我們來認真了解下這經(jīng)常使用的函數(shù)節(jié)流和防抖。

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

函數(shù)節(jié)流:一個函數(shù)執(zhí)行一次后据过,只有大于設(shè)定的執(zhí)行周期后才會執(zhí)行第二次绳锅。有個需要頻繁觸發(fā)函數(shù)期虾,出于優(yōu)化性能角度,在規(guī)定時間內(nèi)壕鹉,只讓函數(shù)觸發(fā)的第一次生效牛郑,后面不生效钉答。

下面主要介紹時間戳和定時器兩種方式來實現(xiàn)節(jié)流函數(shù)仑性。

  • 時間戳實現(xiàn)函數(shù)節(jié)流

根據(jù)函數(shù)節(jié)流的原理,我們也可以不依賴 setTimeout實現(xiàn)函數(shù)節(jié)流。

function throttle(fn, delay) {
    // 記錄上一次函數(shù)觸發(fā)的時間
    var lastTime = 0;
    return function() {
        // 記錄當(dāng)前函數(shù)觸發(fā)的時間
        var nowTime = Date.now();
        if (nowTime - lastTime > delay) {
        // 修正this指向問題
            fn.call(this);
        // 同步時間
          lastTime = nowTime;
        }
    }
}

測試代碼:

// test
function testThrottle(e, content) {
    console.log(e, content);
}
var testThrottleFn = throttle(testThrottle, 1000); // 節(jié)流函數(shù)
document.onmousemove = function (e) {
    testThrottleFn(e, 'throttle'); // 給節(jié)流函數(shù)傳參
}

其實現(xiàn)原理钠怯,通過比對上一次執(zhí)行時間與本次執(zhí)行時間的時間差與間隔時間的大小關(guān)系晦炊,來判斷是否執(zhí)行函數(shù)。若時間差大于間隔時間宁脊,則立刻執(zhí)行一次函數(shù)断国。并更新上一次執(zhí)行時間。

  • 定時器實現(xiàn)函數(shù)節(jié)流
function throttle(fn, delay) {
    var timer;
    return function () {
        var _this = this;
        var args = arguments;
        if (timer) {
            return;
        }
        timer = setTimeout(function () {
            fn.apply(_this, args);
            timer = null; // 在delay后執(zhí)行完fn之后清空timer朦佩,此時timer為假并思,
            throttle觸發(fā)可以進入計時器
        }, delay)
    }
}

測試代碼:

function testThrottle(e, content) {
    console.log(e, content);
}
var testThrottleFn = throttle(testThrottle, 2000); // 節(jié)流函數(shù)
document.onmousemove = function (e) {
    testThrottleFn(e, 'throttle'); // 給節(jié)流函數(shù)傳參
}

上面例子中,如果我們一直在瀏覽器中移動鼠標(比如10s)语稠,則在這10s內(nèi)會每隔2s執(zhí)行一次testThrottle宋彼,這就是函數(shù)節(jié)流。

函數(shù)節(jié)流的目的仙畦,是為了限制函數(shù)一段時間內(nèi)只能執(zhí)行一次输涕。因此,定時器實現(xiàn)節(jié)流函數(shù)通過使用定時任務(wù)慨畸,延時方法執(zhí)行莱坎。在延時的時間內(nèi),方法若被觸發(fā)寸士,則直接退出方法檐什。從而,實現(xiàn)函數(shù)一段時間內(nèi)只執(zhí)行一次弱卡。

函數(shù)節(jié)流的應(yīng)用場景

需要間隔一定時間觸發(fā)回調(diào)來控制函數(shù)調(diào)用頻率

  • DOM 元素的拖拽功能實現(xiàn)(mousemove)
  • 搜索聯(lián)想(keyup)
  • 計算鼠標移動的距離(mousemove)
  • Canvas 模擬畫板功能(mousemove)
  • 滾動加載乃正,加載更多或滾到底部監(jiān)聽
  • 谷歌搜索框,搜索聯(lián)想功能
  • 高頻點擊提交婶博,表單重復(fù)提交

函數(shù)防抖

防抖函數(shù):一個需要頻繁觸發(fā)的函數(shù)瓮具,在規(guī)定時間內(nèi),只讓最后一次生效,前面的不生效名党。

function debounce(fn, delay) {
    var timer = null; 
    return function () {
        var _this = this; // 取debounce執(zhí)行作用域的this
        var args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(function () {
            fn.apply(_this, args); // 用apply指向調(diào)用debounce的對象叹阔,
            相當(dāng)于_this.fn(args);
        }, delay);
    };
}

測試代碼:

function testDebounce(e, content) {
    console.log(e, content);
}
var testDebounceFn = debounce(testDebounce, 1000); // 防抖函數(shù)
document.onmousemove = function (e) {
    testDebounceFn(e, 'debounce'); // 給防抖函數(shù)傳參
}

上面例子中的debounce就是防抖函數(shù),在document中鼠標移動的時候传睹,會在onmousemove最后觸發(fā)的1s后執(zhí)行回調(diào)函數(shù)testDebounce耳幢;如果我們一直在瀏覽器中移動鼠標(比如10s),會發(fā)現(xiàn)會在10+1s后才會執(zhí)行testDebounce函數(shù)(因為clearTimeout(timer))蒋歌,這個就是函數(shù)防抖帅掘。

函數(shù)防抖的應(yīng)用場景

對于連續(xù)的事件響應(yīng)我們只需要執(zhí)行一次回調(diào):

  • 每次 resize/scroll 觸發(fā)統(tǒng)計事件
  • 文本輸入的驗證(連續(xù)輸入文字后發(fā)送 AJAX 請求進行驗證,驗證一次就好)
  • 搜索框搜索輸入堂油。只需用戶最后一次輸入完修档,再發(fā)送請求
  • 手機號、郵箱驗證輸入檢測
  • 窗口大小Resize府框。只需窗口調(diào)整完成后吱窝,計算窗口大小。防止重復(fù)渲染迫靖。

總結(jié)

函數(shù)節(jié)流和函數(shù)去抖的核心其實就是限制某一個方法被頻繁觸發(fā)院峡,其目的都是,降低回調(diào)執(zhí)行頻率系宜,節(jié)省計算資源照激,提高瀏覽器的性能。

更多優(yōu)質(zhì)文章可以訪問GitHub博客盹牧,歡迎帥哥美女前來StarA├!汰寓!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末口柳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子有滑,更是在濱河造成了極大的恐慌跃闹,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毛好,死亡現(xiàn)場離奇詭異望艺,居然都是意外死亡,警方通過查閱死者的電腦和手機肌访,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門荣茫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人场靴,你說我怎么就攤上這事。” “怎么了旨剥?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵咧欣,是天一觀的道長。 經(jīng)常有香客問我轨帜,道長魄咕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任蚌父,我火速辦了婚禮哮兰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苟弛。我一直安慰自己喝滞,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布膏秫。 她就那樣靜靜地躺著右遭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缤削。 梳的紋絲不亂的頭發(fā)上窘哈,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音亭敢,去河邊找鬼滚婉。 笑死,一個胖子當(dāng)著我的面吹牛帅刀,可吹牛的內(nèi)容都是我干的让腹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼劝篷,長吁一口氣:“原來是場噩夢啊……” “哼哨鸭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起娇妓,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤像鸡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后哈恰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體只估,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年着绷,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛔钙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡荠医,死狀恐怖吁脱,靈堂內(nèi)的尸體忽然破棺而出桑涎,到底是詐尸還是另有隱情,我是刑警寧澤兼贡,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布攻冷,位于F島的核電站,受9級特大地震影響遍希,放射性物質(zhì)發(fā)生泄漏等曼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一凿蒜、第九天 我趴在偏房一處隱蔽的房頂上張望禁谦。 院中可真熱鬧,春花似錦废封、人聲如沸州泊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拥诡。三九已至,卻和暖如春氮发,著一層夾襖步出監(jiān)牢的瞬間渴肉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工爽冕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留仇祭,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓颈畸,卻偏偏與公主長得像乌奇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子眯娱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 無意間讀了馮侖的一本書《野蠻生長》徙缴,就一個感悟:牛人成功總是有道理的试伙,不僅僅是運氣,更多的是努力和拼命于样。 這本書怎...
    輝輝隨筆閱讀 189評論 0 0
  • 以前一直是恐懼寫東西的疏叨,因為覺得自己沒有寫作經(jīng)驗,覺得自己沒有邏輯穿剖,寫的亂七八糟的蚤蔓,所以即使自己有很多的話想...
    信念_1dfd閱讀 449評論 0 2
  • 今年的春分時間在3月20日,雖然春分已經(jīng)快要過去了糊余,現(xiàn)在卻是反饋上一個季節(jié):春分--四季占卜的好時機秀又。 不做...
    海鮮Bethany閱讀 575評論 0 0
  • 微演講打卡練習(xí)第385天单寂,每天一分鐘,成為最美好的自己 下午有省里的領(lǐng)導(dǎo)來社區(qū)檢查綜治維穩(wěn)工作涮坐,安排我給...
    古月無語閱讀 139評論 0 2
  • 夕陽與天藍交輝在一起凄贩, 似是白天不愿夜晚的來臨, 可寒冷卻吹了又吹袱讹。 燈光終于亮起, 黑幕也在車如馬龍中愈顯深邃昵时,...
    在下王某某閱讀 329評論 0 0