JavaScript 事件節流和事件防抖

一個網站,想要吸引更多的流量,提升用戶粘性,除了良好的設計和優雅的交互外,最重要的就是加載速度了。沒有用戶願意等,哪怕是1秒,他們均可能再也不來了。這個時候性能優化就顯得十分重要了。css

性能優化的方案中不得不提的是雅虎軍規,列表中總結了不少值得你們注意的地方和解決方案,可供你們參考。固然雅虎軍規並無覆蓋全部的性能優化方案,這裏咱們須要提一下性能優化中的事件優化---事件節流(throttle)與事件防抖(debounce),這兩點在實際應用的十分廣泛html

背景

假如咱們爲DOM綁定了onScroll事件,當使用觸控板,滾動滾輪,或者拖拽滾動條的時候,一秒能夠輕鬆觸發幾十次事件。更加誇張的是手機上的表現:慢慢滑動一下,一秒能夠觸發事件100次之多。這麼高的執行頻率,你的回調函數壓力大可想而知,更加蛋疼的是:函數觸發頻率太高可能會致使的響應速度跟不上觸發頻率,出現延遲,假死或卡頓的現象。那這種就是很是差的體驗。不要覺得這個是小問題,當年,鼎鼎大名的Twitter網站就出現了這個問題:向下滾動 Twitter 信息流的時候,變得很慢,很遲鈍。就是由於 scroll 事件關聯了開銷大的函數致使的。jquery

加上了防抖和節流的函數變得特別有用,why?由於咱們在事件和函數執行之間加了一個控制層,這個控制層控制的是函數是否執行,注意咱們不能去控制 DOM 事件觸發頻率。ajax

介紹完背景,咱們來分別說一下事件節流和事件防抖npm

共同點:都限制函數的執行頻次,達到優化的目的性能優化

不一樣點bash

  • 事件節流app

    處理方法是隻容許一個函數在 x 毫秒內執行一次,跟 防抖 主要的不一樣在於,節流 保證 x 毫秒內至少執行一次。舉一個最近簡單的🌰: 每200ms檢查下滾動位置,並觸發頁面加載函數

  • 事件防抖工具

    處理方法是把觸發很是頻繁的事件(好比key event ,resize)合併成一次執行

說了這麼多,都是概念上的東西,估計你們煩了,立刻進入你們喜歡的環節,荷槍實彈的來一發(你也能夠本身造一個 debounce/throttle 的輪子或者隨便找個博文複製過來。我這裏是直接使用 lodash(還能夠用underscore) 。使用 lodash 自定義構建工具,生成一個 僅包含 _.debounce 或 _.throttle 方法的壓縮庫,,可使用如下的簡單命令便可:

npm i -g lodash-cli
lodash-cli include=debounce,throttle
複製代碼

好了,先獻上事件節流的🌰,供你們參看

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
      body {
        background: #e1e1e1;
        margin:0 auto;
        max-width:600px;
        padding:12px;
      }
      .item {
        height:120px;
        width:100%;
        margin-top:50px;
        padding:20px;
      }
      .color-1 { background: #9BFFBB}
      .color-2 { background: #B9C6FF}
      .color-3 { background: #FFA3D8}
      .color-4 { background: #FF8E9B}
    </style>
</head>
<body>
<h1>這是一個事件節流的🌰 呵呵噠</h1>
<div class="item color-1">Block 1</div>
<div class="item color-2">Block 2</div>
<div class="item color-3">Block 3</div>
<div class="item color-4">Block 4</div>
</body>
<script src="https://cdn.bootcss.com/jquery/2.1.0/jquery.min.js"></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js'></script>
<script>
    $(document).ready(function(){
    // Check every 200ms the scroll position
    $(document).on('scroll', _.throttle(function(){
      check_if_load_more();
    }, 300));

    function check_if_load_more() {
      BottomPixelsFromWindow = 0 + $(document).height() - $(window).scrollTop() -$(window).height();
      if (BottomPixelsFromWindow < 200){
        $('body').append($('.item').clone());
      }
    }
  });
</script>
</html>
複製代碼

再來個事件防抖的,鞏固一下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
      body {
        background: #e1e1e1;
        color: white;
        margin:0 auto;
      }
      .left-part,
      .right-part {
        padding:1%;
        margin:0;
        width:45%;
        float:left;
        min-height:100vh;
        text-align:center;
      }

      .left-part {
        background: #999999;
        color:black;
      }
    </style>
</head>
<body>
<h1>這是一個事件防抖的🌰 呵呵噠</h1>
<div class="left-part">normal resize events<br></div>
<div class="right-part">Debounced resize events<br></div>
</body>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js'></script>
<script>
  $(document).ready(function(){
    var win = $(window);
    var left_part = $('.left-part');
    var right_part = $('.right-part');

    function print_info(div) {
      div.append(win.width() + ' x ' + win.height() +  '<br>');
    }

    $(window).on('resize', function(){
      print_info(left_part);
    });

    $(window).on('resize', _.debounce(function() {
      print_info(right_part);
    }, 400));
  });
</script>
</html>

複製代碼

說了這麼多,事件節流和事件防抖真的用處很大 若是記不住,你也能夠比喻着想:

事件節流像是班車:固定在一段時間後執行,不會等乘客(事件),到點發車

事件防抖像是黑車:說是再等五分鐘就走,可是若是又有人上車了(在5分鐘內再次觸發事件),那你又得等5分鐘才能再出發(從新計時)

不恰當的🌰哈 ,幫助記憶

未經本人容許,不得轉載,文章有疏漏淺薄之處,請各位大神斧正

相關文章
相關標籤/搜索