jQuery 性能優(yōu)化

關(guān)于選擇器

  • 總是從 ID 選擇器開始繼承
    jQuery 選擇器對(duì) ID 的選擇是使用原生的 getElementById() 方法焦除,因此從最近的 id 選擇器開始繼承梧油,可以避免不必要的 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 來修飾 id $(#footer #footernav)
    3. 如果使用屬性選擇器,盡量使用 tag 來修飾 $(input[row='c3221'])
  • 盡量使用 ID 代替 class
    ID 選擇器調(diào)用原生 getElementById() 方法是所有選擇中速度最快的跋核。
    具體使用還是要更具實(shí)際情況粥庄,組織好代碼以及命名規(guī)范丧失。

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

    jQuery(expression, context)
    

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

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

    個(gè)人感覺這一點(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)用改善選擇器多次選擇的性能問題膘流。

       $('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)成的命名空間的感覺

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

關(guān)于 DOM 操作

  • 使用 DocumentFrame 的思想

    直接操作 DOM 的成本睡扬,不管是使用原生 JavaScript 還是 jQuery 的開銷都很大,所以每次進(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 保存起來
      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)于事件綁定問題

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

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

    主要使用到的技術(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ì)于效率來說馆匿,這個(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í)間更短渐北,更快的開始執(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)化指南赃蛛,今天看了一下,順便將文章重新組織了一下搀菩,拿出來和大家分享呕臂,如有侵權(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)系作者
  • 序言:七十年代末秕磷,一起剝皮案震驚了整個(gè)濱河市诵闭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌澎嚣,老刑警劉巖疏尿,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異易桃,居然都是意外死亡褥琐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門晤郑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敌呈,“玉大人,你說我怎么就攤上這事造寝】暮椋” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵诫龙,是天一觀的道長(zhǎng)析显。 經(jīng)常有香客問我,道長(zhǎng)签赃,這世上最難降的妖魔是什么谷异? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮锦聊,結(jié)果婚禮上歹嘹,老公的妹妹穿的比我還像新娘。我一直安慰自己孔庭,他們只是感情好尺上,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般尖昏。 火紅的嫁衣襯著肌膚如雪仰税。 梳的紋絲不亂的頭發(fā)上构资,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天抽诉,我揣著相機(jī)與錄音,去河邊找鬼吐绵。 笑死迹淌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的己单。 我是一名探鬼主播唉窃,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼纹笼!你這毒婦竟也來了纹份?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤廷痘,失蹤者是張志新(化名)和其女友劉穎蔓涧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笋额,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡元暴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兄猩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茉盏。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖枢冤,靈堂內(nèi)的尸體忽然破棺而出鸠姨,到底是詐尸還是另有隱情,我是刑警寧澤淹真,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布讶迁,位于F島的核電站,受9級(jí)特大地震影響趟咆,放射性物質(zhì)發(fā)生泄漏添瓷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一值纱、第九天 我趴在偏房一處隱蔽的房頂上張望鳞贷。 院中可真熱鬧,春花似錦虐唠、人聲如沸搀愧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咱筛。三九已至搓幌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迅箩,已是汗流浹背溉愁。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饲趋,地道東北人拐揭。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像奕塑,于是被迫代替她去往敵國(guó)和親堂污。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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

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