SlideShare a Scribd company logo
1 of 93
jQuery Performance Tips
     Frontrend Vol.4 powered by CyberAgent
@pocotan001
  Hayato Mizuno
マシンの仕事を


速くするには、少なくしろ
   - 速く動くコードの書き方 -




                     photo by Andrew Morrell Photography
最適化されたコード?

$(document.getElementById('target').

getElementsByTagName('p'))...




          パフォーマンス◎ 可読性△
最適化されたコード?

$('#target p')...




     パフォーマンス△ 可読性◎
利用率の推移

                                     jQuery

                                                                               54.9%
          None
                                   50.8%
 49.1%

                  46.7%


 42.8%

                                                                               39.2%

2012/01          2012/05         2012/09                                     2013/01


                           http://w3techs.com/technologies/history_overview/javascript_library/all
アジェンダ



- ファイルサイズを減らす

- セレクタのチューニング

- リフローの影響を考える
ファイルサイズを減らす
34kb    33kb    33kb
                        32kb
                30kb                                     30kb
        27kb


20kb




1.3.2   1.4.4   1.5.2   1.6.4   1.7.2   1.8.3   1.9.0   2.0.0b1
1kbにつき1msのパース時間
                        (モバイルデバイス)


                                 34kb    33kb    33kb
                         32kb
                30kb                                      30kb
        27kb


20kb




1.3.2   1.4.4   1.5.2    1.6.4   1.7.2   1.8.3   1.9.0   2.0.0b1
IE6-8対応用スニペット

<!--[if lt IE 9]>

    <script src="jquery-1.9.0.js"></script>

<![endif]-->

<!--[if gte IE 9]><!-->

    <script src="jquery-2.0.0.js"></script>

<!--[endif]-->
http://gruntjs.com/
34kb
                                        33kb    33kb
                        32kb
                30kb                                     30kb
        27kb



20kb




                                                 23kb



                                                          20kb
1.3.2   1.4.4   1.5.2   1.6.4   1.7.2   1.8.3   1.9.0   2.0.0b1
jquery / README.md - GitHub
モジュール



- ajax
- css
- effects
- offset
- dimensions
モジュール          $ grunt custom:-ajax,-css




- ajax
- css
- effects
- offset
- dimensions
モジュール          $ grunt custom:-ajax,-css
               Running "custom:-ajax,-
               css" (custom) task
               Creating custom build...
- ajax         Running "build:dist/

- css          jquery.js:*:-ajax:-
               css" (build) task
               Excluding css

- effects       (src/css.js)
               Excluding ajax
               (src/ajax.js)

- offset        Excluding ajax/script
               (src/ajax/script.js)
               Excluding ajax/jsonp
- dimensions   (src/ajax/jsonp.js)
               Excluding ajax/xhr
               (src/ajax/xhr.js)
削除済み/削除予定のAPI



$.uuid, $.attrFn, $.deletedIds,
$.curCSS(), $.sub(),
$.offset.bodyOffset(),
$.fn.andSelf(), $.fn.data('events'),
Deferred.isResolved(),
Deferred.isRejected() ...いっぱい。
削除済み/予定のAPI
<script src="jquery-1.9.0.js"></script>

<script src="jquery-migrate.js"></script>
$.uuid, $.attrFn, $.deletedIds, $.curCSS(),
<script>
$.sub(),($.browser.msie) ...
    if $.offset.bodyOffset(),

</script>
$.fn.andSelf(), $.fn.data('events'),
Deferred.isResolved(),
        Migrateプラグインが便利!
Deferred.isRejected() ...いっぱい。
削除済み/予定のAPI



$.uuid, $.attrFn, $.deletedIds, $.curCSS(),
$.sub(), $.offset.bodyOffset(),
      jQuery.browser is deprecated
$.fn.andSelf(), $.fn.data('events'),
Deferred.isResolved(),
Deferred.isRejected() ...いっぱい。
jquery-migrate / warnings.md - GitHub
セレクタのチューニング
速いセレクタランキング



1. $('#id')
2. $('tag')
3. $('.class')         速い

4. $(':first-child')
5. $(':first')
速いセレクタランキング



1. getElementById
2. getElementsByTagName
3. getElementsByClassName   速い

4. querySelectorAll
5. jQuery Extensions
Example 1



  $('#target p')




       querySelectorAll
Example 1



  $('#target').find('p')




         getElementById
                 +
              .find()
                 +
      getElementsByTagName
Example 1




            +   43%
            (Chrome 24)



                          http://jsperf.com/jquery-child-selectors-ptan/2
Example 2



  $('#target').find('p:first')




               querySelectorAll
                      +
            getElementsByTagName
                      +
               jQuery Extension
Example 2



  $('#target').find('p:first-child')




             querySelectorAll
Example 2



  $('#target').find('p').first()




            getElementsByTagName
                       +
                   .first()
Example 2



  $('#target').find('p').eq(0)




            getElementsByTagName
                       +
                    .eq(0)
Example 2



  $.fn.first = function() {
       return this.eq( 0 );

  };


                  $.fn.first の中身
Example 2




            +   87%
            (Chrome 24)
                          http://jsperf.com/jquery-first-selectors-ptan/2
Example 3



  $('#target').find('p[title="test"]')




               querySelectorAll
Example 3



  $('#target').find('p').filter('[title="test"]')




              getElementsByTagName
                         +
                     .filter()
Example 3




            -   44%
                (Chrome 24)



                              http://jsperf.com/jquery-attribute-selectors-ptan/2
キャッシュの活用も忘れずに

var $target = $('#target'),
      $p = $target.find('p');


$target.on('click', function(e) {

      $p.toggle();
});
リフローの影響を考える
HTML


          DOM


視覚部分を
表すツリー   レンダーツリー   描画


         CSSOM


          CSS
CSS Reflow - jQuery.com
DOMツリー


              html


   head                   body


   title             h1          p


[text node]    [text node]   [text node]
レンダーツリー                       ツリーに挿入されない要素




               root
                                 display:none


   head                    body


    title             h1              p


 [text line]    [text line]      [text line]
レンダーツリー                       ツリーに挿入されない要素




               root
                                display:block


   head                    body


    title             h1             p


 [text line]    [text line]      [text line]

      リフロー!レイアウトの計算を行う処理のこと
HTML


  DOM


レンダーツリー   描画


 CSSOM


  CSS
HTML


       DOM     リペイント!


JS   レンダーツリー   再描画


      CSSOM


       CSS
HTML
$('p').css('margin', '5px')

              DOM


 JS        レンダーツリー            再描画


             CSSOM             +
                              リフロー

               CSS
HTML
$('p').css('color', 'red')

              DOM


 JS        レンダーツリー           再描画


             CSSOM


               CSS
リフロー 2?

$('p').css('margin', '5px')




$('p').css('margin', '5px')
1 位置変更がないため
リフロー 4?

$('p').css('margin', '5px')
      .css('padding', '5px')
      .css('top', '5px')
      .css('left', '5px');
1 可能な限り収束される
収束が難しいケース

$('p').css('margin', '5px')
      .css('padding', '5px')
      .css('top', $target.height())
      .css('left', '5px');
2 ...あれ?
最近のChrome賢すぎ...
                  photo by pedrosimoes7
2 Safariでやります
    (スミマセン...)
リフロー?リペイントのみ?


- display
- visibility
- opacity
- border
- border-radius
リフロー?リペイントのみ?


- display
- visibility      リペイントのみ

- opacity         リペイントのみ

- border
- border-radius   リペイントのみ
リペイントのみでもモノによっては高コスト


-   color: rgba()
-   opacity
-   background: linear-gradient()
-   border-radius
- text-shadow
- ... etc
                                    See also
リフローが発生する可能性のあるトリガー


- CSSの変更/取得
 css(), addClass(), show(), animate() ...

- DOM要素の操作
 html(), text(), append(), focus() ...

- 特定のプロパティの取得
 offset(), position() ...

- ユーザー操作
 ウィンドウサイズの変更, スクロール, テキストの入力 ...
                                            See also
不要なリフローを避ける
Example 1



  $('<p>test</p>').appendTo('body').hide();




                 生成時に色々と追加が
                   必要なケース
Example 1



  $('<p>test</p>').hide().appendTo('body');




                  描画する前に行う
Example 1




            Before
Example 1




            After
Example 2



  $('<img src="200x100.jpg">').
      appendTo('body');




                  imgを生成するケース
Example 2



  $('<img src="200x100.jpg" width="200"
  height="150">').

      appendTo('body');


               描画の領域を明示しておく
                 CSSで指定しても×
Example 2




            Before
Example 2




            After
Example 3



  $('p').css('top', $target.offset().top)
        .css('left', $target.offset().left);




            複数回に分けて実行されるcss()
Example 3



  $('p').css({
        top: $target.offset().top,

        left: $target.offset().left
  });



              1回のcss()にまとめる
Example 3



  $('p').css({
        top: $target.offset().top,

        left: $target.offset().left
  });


            リフローが必要な取得系メソッド
Example 3



  var offset = $target.offset();


  $('p').css({
        top: offset.top,

        left: offset.left
  });
                 可能ならキャッシュして使い回す
Example 3




            Before
Example 3




            After
Example 4



  <script src="jquery.js"></script>

  <script src="jquery-ui.js"></script>

  <script>

  $(function(){ $('#target').accordion(...); });

  </script>

  </body>
              UI表示後にスタイルを変更するケース
Example 4




    表示             JS          変更




            読み込み, パース, 実行...
             この間は待ち時間
Example 4



  <script src="jquery.js"></script>

  <script src="jquery-ui.js"></script>

  <script>

  $(function(){ $('#target').accordion(...); });

  </script>

  </head>
               <head> に移す
Example 4




    JS      表示&更新
Example 4



その他の代替案
- スタイル付けはCSSでやる

- async属性で非同期にする (IE10∼)

- 既存の非同期ローダーに乗っかる (RequireJSとか)
ボトルネックを解消する
ボトルネックになりそうなところ


- 描画コストの高いCSSプロパティ

- アニメーション

- ループ処理

- scroll, resize などの発火回数の多いイベント

- ... etc
Google Chrome Canary
jQuery Animations < CSS3




    http://dev.opera.com/articles/view/css3-vs-jquery-animations/
requestAnimationFrame




  https://github.com/gnarf37/jquery-requestAnimationFrame
throttle / debounce




http://ktkne.st/elab/post/2012/strcount-throttle-debounce.html
その他



- スタイルの変更は出来るだけ末端要素で行う


- アニメーションは固定配置にする


- テーブルレイアウトをしない
戒めのお言葉
小さな効率は忘れよう。
時間の97%について語ろう。
早まった最適化は諸悪の根源だ。
              Tony Hoare?




                            photo by glingl
Thank you




            photo by Furryscaly

More Related Content

What's hot

What's hot (20)

第5回勉強会
第5回勉強会第5回勉強会
第5回勉強会
 
はじめよう Backbone.js
はじめよう Backbone.jsはじめよう Backbone.js
はじめよう Backbone.js
 
Async Enhancement
Async EnhancementAsync Enhancement
Async Enhancement
 
Introduction for Browser Side MVC
Introduction for Browser Side MVCIntroduction for Browser Side MVC
Introduction for Browser Side MVC
 
Knockout を用いた Firefox OS アプリケーションの開発
Knockout を用いた Firefox OS アプリケーションの開発Knockout を用いた Firefox OS アプリケーションの開発
Knockout を用いた Firefox OS アプリケーションの開発
 
第4回勉強会 Groovyの文法からSpockまで
第4回勉強会 Groovyの文法からSpockまで第4回勉強会 Groovyの文法からSpockまで
第4回勉強会 Groovyの文法からSpockまで
 
Xamarin で ReactiveUI を使ってみた
Xamarin で ReactiveUI を使ってみたXamarin で ReactiveUI を使ってみた
Xamarin で ReactiveUI を使ってみた
 
DjangoでさくっとWeb アプリケーション開発をする話
DjangoでさくっとWeb アプリケーション開発をする話DjangoでさくっとWeb アプリケーション開発をする話
DjangoでさくっとWeb アプリケーション開発をする話
 
AsyncTask アンチパターン
AsyncTask アンチパターンAsyncTask アンチパターン
AsyncTask アンチパターン
 
⑲jQueryをおぼえよう!その5
⑲jQueryをおぼえよう!その5⑲jQueryをおぼえよう!その5
⑲jQueryをおぼえよう!その5
 
The master plan of scaling a web application
The master plan ofscaling a web applicationThe master plan ofscaling a web application
The master plan of scaling a web application
 
Griffon10 in groovy_fx
Griffon10 in groovy_fxGriffon10 in groovy_fx
Griffon10 in groovy_fx
 
大規模なJavaScript開発の話
大規模なJavaScript開発の話大規模なJavaScript開発の話
大規模なJavaScript開発の話
 
ES6 in Practice
ES6 in PracticeES6 in Practice
ES6 in Practice
 
最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
Pyramid入門
Pyramid入門Pyramid入門
Pyramid入門
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovy
 
React入門-JSONを取得して表示する
React入門-JSONを取得して表示するReact入門-JSONを取得して表示する
React入門-JSONを取得して表示する
 
concrete5デザインカスタマイズに必要なPHPの知識
concrete5デザインカスタマイズに必要なPHPの知識concrete5デザインカスタマイズに必要なPHPの知識
concrete5デザインカスタマイズに必要なPHPの知識
 

Similar to jQuery Performance Tips – jQueryにおける高速化 -

速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
Kazunari Hara
 
20110714 j queryベーシック
20110714 j queryベーシック20110714 j queryベーシック
20110714 j queryベーシック
良太 増子
 

Similar to jQuery Performance Tips – jQueryにおける高速化 - (20)

Magento meet up Tokyo#1 for Design
Magento meet up Tokyo#1 for DesignMagento meet up Tokyo#1 for Design
Magento meet up Tokyo#1 for Design
 
20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会
 
Native x Webでいいとこどり開発 ~ピグトーク~
Native x Webでいいとこどり開発 ~ピグトーク~Native x Webでいいとこどり開発 ~ピグトーク~
Native x Webでいいとこどり開発 ~ピグトーク~
 
HTML5 on ASP.NET
HTML5 on ASP.NETHTML5 on ASP.NET
HTML5 on ASP.NET
 
⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2⑯jQueryをおぼえよう!その2
⑯jQueryをおぼえよう!その2
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 
20110714 j queryベーシック
20110714 j queryベーシック20110714 j queryベーシック
20110714 j queryベーシック
 
jQuery Mobile 最新情報 & Tips
jQuery Mobile 最新情報 & TipsjQuery Mobile 最新情報 & Tips
jQuery Mobile 最新情報 & Tips
 
CodeIgniterによるPhwittr
CodeIgniterによるPhwittrCodeIgniterによるPhwittr
CodeIgniterによるPhwittr
 
Rails3.1rc4を試してみた
Rails3.1rc4を試してみたRails3.1rc4を試してみた
Rails3.1rc4を試してみた
 
Ajax 応用
Ajax 応用Ajax 応用
Ajax 応用
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
 
Aaなゲームをjsで
AaなゲームをjsでAaなゲームをjsで
Aaなゲームをjsで
 
Aaなゲームをjsで
AaなゲームをjsでAaなゲームをjsで
Aaなゲームをjsで
 
第四回 JavaScriptから始めるプログラミング2016
第四回 JavaScriptから始めるプログラミング2016第四回 JavaScriptから始めるプログラミング2016
第四回 JavaScriptから始めるプログラミング2016
 
イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門
 
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
毎秒2000Requestを捌くPerl製CMSの内部構造(Debianサーバ1台にて)
 

More from Hayato Mizuno

More from Hayato Mizuno (10)

レスポンシブWebデザインでうまくやるための考え方
レスポンシブWebデザインでうまくやるための考え方レスポンシブWebデザインでうまくやるための考え方
レスポンシブWebデザインでうまくやるための考え方
 
"今" 使えるJavaScriptのトレンド
"今" 使えるJavaScriptのトレンド"今" 使えるJavaScriptのトレンド
"今" 使えるJavaScriptのトレンド
 
メンテナブルPSD
メンテナブルPSDメンテナブルPSD
メンテナブルPSD
 
赤い秘密
赤い秘密赤い秘密
赤い秘密
 
なんでCSSすぐ死んでしまうん
なんでCSSすぐ死んでしまうんなんでCSSすぐ死んでしまうん
なんでCSSすぐ死んでしまうん
 
フロントエンドの求めるデザイン
フロントエンドの求めるデザインフロントエンドの求めるデザイン
フロントエンドの求めるデザイン
 
Hello jQuery - 速習jQuery +綺麗なコードを書くためのヒント -
Hello jQuery - 速習jQuery +綺麗なコードを書くためのヒント -Hello jQuery - 速習jQuery +綺麗なコードを書くためのヒント -
Hello jQuery - 速習jQuery +綺麗なコードを書くためのヒント -
 
レンダリングを意識したパフォーマンスチューニング
レンダリングを意識したパフォーマンスチューニングレンダリングを意識したパフォーマンスチューニング
レンダリングを意識したパフォーマンスチューニング
 
CoffeeScriptってなんぞ?
CoffeeScriptってなんぞ?CoffeeScriptってなんぞ?
CoffeeScriptってなんぞ?
 
ノンプログラマーのためのjQuery入門
ノンプログラマーのためのjQuery入門ノンプログラマーのためのjQuery入門
ノンプログラマーのためのjQuery入門
 

jQuery Performance Tips – jQueryにおける高速化 -