jQuery 性能優(yōu)化

關(guān)于選擇器

  • 總是從 ID 選擇器開(kāi)始繼承
    jQuery 選擇器對(duì) ID 的選擇是使用原生的 getElementById() 方法,因此從最近的 id 選擇器開(kāi)始繼承,可以避免不必要的 DOM 遍歷和循環(huán) (單個(gè)元素直接選擇,多個(gè)元素遍歷數(shù)目可以減少很多)

  • 在 class 前使用 tag (標(biāo)簽名)
    jQuery 對(duì)元素選擇使用的也是原生的 getElementsByTagName() 方法使用 tag 標(biāo)簽修飾 class 時(shí)的注意點(diǎn)

    1. 不要使用 tag 修飾 id, id永遠(yuǎn)是最快的 $(input #username)
    2. 不要畫蛇添足的使用 id 來(lái)修飾 id $(#footer #footernav)
    3. 如果使用屬性選擇器,盡量使用 tag 來(lái)修飾 $(input[row='c3221'])
  • 盡量使用 ID 代替 class
    ID 選擇器調(diào)用原生 getElementById() 方法是所有選擇中速度最快的。
    具體使用還是要更具實(shí)際情況,組織好代碼以及命名規(guī)范。

  • 給選擇器一個(gè)上下文
    jQuery 選擇器中有一個(gè)這樣的選擇器,它能指定上下文。

    jQuery(expression, context)
    

    通過(guò)使用它可以縮小選擇器在 DOM 中搜索的范圍,達(dá)到節(jié)省事件,提高效率

    $('.myDiv')
    -- 推薦寫法 --   
    $('.myDiv', $('#context'))
    

    個(gè)人感覺(jué)這一點(diǎn)與 $('#context .myDiv') 類似

  • 正確使用子選擇器與后代選擇器
    與 CSS 的子選擇器和后代選擇器類似使用的時(shí)候避免只是用子選擇器,卻使用了后代選擇器的情況

    $('parentSelector childrenSelector')    
    // parentSelector 節(jié)點(diǎn)下任意層級(jí)(后代)的 childrenSelector 匹配值
    
    $('parentSelector > childrenSelector')      
    // parentSelector 節(jié)點(diǎn)子元素中滿足 childrenSelector 匹配值
    
  • 緩存 jQuery 對(duì)象與鏈?zhǔn)秸{(diào)用

    永遠(yuǎn)不要讓相同的選擇器在代碼里出現(xiàn)多次,每次都以為這一個(gè)新的遍歷查詢
    jQuery 的鏈?zhǔn)秸{(diào)用機(jī)制可以減少同一選擇器的多次出現(xiàn)

    可選的 tips:

    1. 為了區(qū)分普通的 JavaScript 對(duì)象和 jQuery 對(duì)象,可以在 jQuery 對(duì)象名前加上 $ 符號(hào)。

    2. 可以使用 jQuery 的鏈?zhǔn)秸{(diào)用改善選擇器多次選擇的性能問(wèn)題。

       $('some-selector').on('click',function(){})
                         .on('mouseover', function(){})
                         .on('mouseout', function(){})
       -- 避免這樣的寫法 --
       $('some-selector').on('click',function(){})
       $('some-selector').on('mouseover', function(){})
       $('some-selector').on('mouseout', function(){})
      
    3. 可以按照自己的需求將 jQuery 對(duì)象存儲(chǔ)在一個(gè)對(duì)象里面,從對(duì)象里面直接取 jQuery 對(duì)象,同時(shí)生成了一個(gè) $ 構(gòu)成的命名空間的感覺(jué)

       window.$my = {
           header: $('head'),
           content: $('div .content'),
           footer: $('footer')
       }
      

關(guān)于 DOM 操作

  • 使用 DocumentFrame 的思想

    直接操作 DOM 的成本,不管是使用原生 JavaScript 還是 jQuery 的開(kāi)銷都很大,所以每次進(jìn)行 DOM 操作都盡可能的一次更新多個(gè)元素,在原生 JavaScript 中表現(xiàn)為使用 DocumentFrame 的方式進(jìn)行 DOM 更新,在 jQuery 中推薦先將需要添加的 DOM 結(jié)構(gòu)用 String 拼接好,一次 DOM 操作更新多個(gè) DOM

      var top_100_li = [...],
      $mylist = $('#mylist'),
      top_100_listring = '';
      // 先使用 top_100_listring 將要添加的 list string 保存起來(lái)
      for(var i = 0, len = top_100_li.length; i < len ; i++) {
          top_100_listring += '<li>' + tp_100_li[i] + '</li>';
      }
      // 一次 DOM 操作更新 100 個(gè) list
      $mylist.html(top_100_listing);
    
      -- 每次都操作DOM的低效使用形式 --
    
      var top_100_li = [...],
      $mylist = $('#mylist'),
      top_100_listring = '';
      for(var i = 0, len = top_100_li.length; i < len ; i++) {
          // 每次都執(zhí)行 DOM 更新操作
          $mylist.append('<li>' + tp_100_li[i] + '</li>');
      }
    

關(guān)于事件綁定問(wèn)題

  • 盡可能的使用冒泡與捕獲的方式,避免不必要的事件綁定

    除非在特殊情況下,否則每個(gè) js 事件都會(huì)冒泡到父級(jí)節(jié)點(diǎn),當(dāng)一個(gè)父級(jí)節(jié)點(diǎn)的后代都具有同樣的事件綁定時(shí),將事件綁定在父級(jí)節(jié)點(diǎn)上能代理效率很低的為每個(gè)子元素都添加事件監(jiān)聽(tīng)。

    主要使用到的技術(shù)是 event 對(duì)象包含 target || srcElement 屬性,表明具體由哪一個(gè)元素觸發(fā)了事件。

    $('table .myTable').off().on('click', function(e) {
        var ev = e || window.event,
            target = ev.target || ev.srcElement,
            $target = $(target);
    
        //如果只是對(duì)特定元素執(zhí)行事件
        if($target ... 不是特定元素 ){
            return
        }
        // $target.doSomething
    })
    -- 不推薦的寫法 --
    $('table .myTable td').off().on('click', function(e) {
        // doSometing ...
    })
    
  • 慎用 .live()方法
    這個(gè)方法個(gè)人學(xué)習(xí)工作中使用較少,僅供讀者參考。
    jQuery 1.3.1 版本之后增加的方法,功能是為新增的 DOM 元素動(dòng)態(tài)綁定事件。但對(duì)于效率來(lái)說(shuō),這個(gè)方法比較占用資源。所以建議不使用。

      $('p').live('click', function() {
          // doSomething ...
      })
      $('body').append('<p>新增的 p 元素</p>')     // 此時(shí)的 p 元素以及綁定了對(duì)應(yīng)的事件
       -- 推薦寫法 --
      $('body').append(
          $('<p>新增的 p 元素</p>')
          .on('click', function() {
              // doSomething ...
          })
      )
    

其他方法

  • 壓縮 JavaScript

    壓縮 JavaScript 代碼可以使加載代碼的時(shí)間更短,更快的開(kāi)始執(zhí)行對(duì)應(yīng)的函數(shù)和方法。能減少用戶等待的時(shí)間提升用戶體驗(yàn)。

  • 使用 data() 方法存儲(chǔ)臨時(shí)變量

    // 不使用data()方法
    $(function() {
        var flag = false;
        $('button').on('click', function() {
            if(flag) {
                $('p').text('true');
                flag = false;
            }
            else {
                $('p').text('false');
                flag = true;   
            }
        })
    })
    // 使用data()方法
    $(function() {
        $('button').on('click', function() {
            if($('p').data('flag')) {
                $('p').text('true');
                $('p').data('flag', false)
            }
            else {
                $('p').text('false');
                $('p').data('flag', true)
            }
        })
    })
    

不知道什么時(shí)候網(wǎng)盤里面多了個(gè)幾篇 jQuery性能優(yōu)化指南,今天看了一下,順便將文章重新組織了一下,拿出來(lái)和大家分享,如有侵權(quán)請(qǐng)聯(lián)系<a href="mailto:swuyxr@163.com">swuyxr@163.com</a>刪除。

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 一、注意定義jQuery變量的時(shí)候添加var關(guān)鍵字 這個(gè)不僅僅是jQuery,所有javascript開(kāi)發(fā)過(guò)程中,...
    小明yz閱讀 882評(píng)論 0 7
  • title: 《鋒利的jQuery》十一、jQuery性能優(yōu)化date: 2017-08-16 22:18:00t...
    Gary23閱讀 448評(píng)論 0 1
  • 1.JQuery 基礎(chǔ) 改變web開(kāi)發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無(wú)需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性。 1....
    LaBaby_閱讀 1,518評(píng)論 0 2
  • 1.JQuery 基礎(chǔ) 改變web開(kāi)發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無(wú)需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性。 1....
    LaBaby_閱讀 1,279評(píng)論 0 1
  • 使用合適的選擇器 不同的選擇器有性能差異,以下為性能從好到壞: $("#id")使用id來(lái)定位無(wú)疑是最佳提高性能的...
    大橙子CZ閱讀 358評(píng)論 0 0

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