Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
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                                                                         ...
アジェンダ- ファイルサイズを減らす- セレクタのチューニング- リフローの影響を考える
ファイルサイズを減らす
34kb    33kb    33kb                        32kb                30kb                                     30kb        27kb2...
1kbにつき1msのパース時間                        (モバイルデバイス)                                 34kb    33kb    33kb                    ...
IE6-8対応用スニペット<!--[if lt IE 9]>    <script src="jquery-1.9.0.js"></script><![endif]--><!--[if gte IE 9]><!-->    <script sr...
http://gruntjs.com/
34kb                                        33kb    33kb                        32kb                30kb                  ...
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           ...
削除済み/削除予定のAPI$.uuid, $.attrFn, $.deletedIds,$.curCSS(), $.sub(),$.offset.bodyOffset(),$.fn.andSelf(), $.fn.data(events),Defe...
削除済み/予定のAPI<script src="jquery-1.9.0.js"></script><script src="jquery-migrate.js"></script>$.uuid, $.attrFn, $.deletedIds,...
削除済み/予定のAPI$.uuid, $.attrFn, $.deletedIds, $.curCSS(),$.sub(), $.offset.bodyOffset(),      jQuery.browser is deprecated$.f...
jquery-migrate / warnings.md - GitHub
セレクタのチューニング
速いセレクタランキング1. $(#id)2. $(tag)3. $(.class)         速い4. $(:first-child)5. $(:first)
速いセレクタランキング1. getElementById2. getElementsByTagName3. getElementsByClassName   速い4. querySelectorAll5. jQuery Extensions
Example 1  $(#target p)       querySelectorAll
Example 1  $(#target).find(p)         getElementById                 +              .find()                 +      getElem...
Example 1            +   43%            (Chrome 24)                          http://jsperf.com/jquery-child-selectors-ptan/2
Example 2  $(#target).find(p:first)               querySelectorAll                      +            getElementsByTagName ...
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                         +          ...
Example 3            -   44%                (Chrome 24)                              http://jsperf.com/jquery-attribute-se...
キャッシュの活用も忘れずに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...
レンダーツリー                       ツリーに挿入されない要素               root                                 display:none   head         ...
レンダーツリー                       ツリーに挿入されない要素               root                                display:block   head         ...
HTML  DOMレンダーツリー   描画 CSSOM  CSS
HTML       DOM     リペイント!JS   レンダーツリー   再描画      CSSOM       CSS
HTML$(p).css(margin, 5px)              DOM JS        レンダーツリー            再描画             CSSOM             +               ...
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  ...
リフローが発生する可能性のあるトリガー- CSSの変更/取得 css(), addClass(), show(), animate() ...- DOM要素の操作 html(), text(), append(), focus() ...- 特...
不要なリフローを避ける
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);               描画の領域を明示しておく          ...
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).acc...
Example 4    表示             JS          変更            読み込み, パース, 実行...             この間は待ち時間
Example 4  <script src="jquery.js"></script>  <script src="jquery-ui.js"></script>  <script>  $(function(){ $(#target).acc...
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 / debouncehttp://ktkne.st/elab/post/2012/strcount-throttle-debounce.html
その他- スタイルの変更は出来るだけ末端要素で行う- アニメーションは固定配置にする- テーブルレイアウトをしない
戒めのお言葉
小さな効率は忘れよう。時間の97%について語ろう。早まった最適化は諸悪の根源だ。              Tony Hoare?                            photo by glingl
Thank you            photo by Furryscaly
jQuery Performance Tips – jQueryにおける高速化 -
jQuery Performance Tips – jQueryにおける高速化 -
jQuery Performance Tips – jQueryにおける高速化 -
jQuery Performance Tips – jQueryにおける高速化 -
Upcoming SlideShare
Loading in …5
×

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

14,318 views

Published on

リッチなWebアプリケーションに対するニーズの増加に伴い、JavaScriptで十分なパフォーマンスを担保することが難しくなってきています。とりわけ、スマートフォンのような非力なデバイスでは一層シビアなチューニングが求められるでしょう。本セッションでは、もっともポピュラーなJavaScriptライブラリである「jQuery」を中心とした、いくつかのパフォーマンス解決のためのヒントについてご紹介させていただきます。

http://frontrend.github.com/events/04/#pocotan001

Published in: Technology
  • Be the first to comment

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

  1. 1. jQuery Performance Tips Frontrend Vol.4 powered by CyberAgent
  2. 2. @pocotan001 Hayato Mizuno
  3. 3. マシンの仕事を速くするには、少なくしろ - 速く動くコードの書き方 - photo by Andrew Morrell Photography
  4. 4. 最適化されたコード?$(document.getElementById(target).getElementsByTagName(p))... パフォーマンス◎ 可読性△
  5. 5. 最適化されたコード?$(#target p)... パフォーマンス△ 可読性◎
  6. 6. 利用率の推移 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
  7. 7. アジェンダ- ファイルサイズを減らす- セレクタのチューニング- リフローの影響を考える
  8. 8. ファイルサイズを減らす
  9. 9. 34kb 33kb 33kb 32kb 30kb 30kb 27kb20kb1.3.2 1.4.4 1.5.2 1.6.4 1.7.2 1.8.3 1.9.0 2.0.0b1
  10. 10. 1kbにつき1msのパース時間 (モバイルデバイス) 34kb 33kb 33kb 32kb 30kb 30kb 27kb20kb1.3.2 1.4.4 1.5.2 1.6.4 1.7.2 1.8.3 1.9.0 2.0.0b1
  11. 11. 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]-->
  12. 12. http://gruntjs.com/
  13. 13. 34kb 33kb 33kb 32kb 30kb 30kb 27kb20kb 23kb 20kb1.3.2 1.4.4 1.5.2 1.6.4 1.7.2 1.8.3 1.9.0 2.0.0b1
  14. 14. jquery / README.md - GitHub
  15. 15. モジュール- ajax- css- effects- offset- dimensions
  16. 16. モジュール $ grunt custom:-ajax,-css- ajax- css- effects- offset- dimensions
  17. 17. モジュール $ 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)
  18. 18. 削除済み/削除予定のAPI$.uuid, $.attrFn, $.deletedIds,$.curCSS(), $.sub(),$.offset.bodyOffset(),$.fn.andSelf(), $.fn.data(events),Deferred.isResolved(),Deferred.isRejected() ...いっぱい。
  19. 19. 削除済み/予定の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() ...いっぱい。
  20. 20. 削除済み/予定のAPI$.uuid, $.attrFn, $.deletedIds, $.curCSS(),$.sub(), $.offset.bodyOffset(), jQuery.browser is deprecated$.fn.andSelf(), $.fn.data(events),Deferred.isResolved(),Deferred.isRejected() ...いっぱい。
  21. 21. jquery-migrate / warnings.md - GitHub
  22. 22. セレクタのチューニング
  23. 23. 速いセレクタランキング1. $(#id)2. $(tag)3. $(.class) 速い4. $(:first-child)5. $(:first)
  24. 24. 速いセレクタランキング1. getElementById2. getElementsByTagName3. getElementsByClassName 速い4. querySelectorAll5. jQuery Extensions
  25. 25. Example 1 $(#target p) querySelectorAll
  26. 26. Example 1 $(#target).find(p) getElementById + .find() + getElementsByTagName
  27. 27. Example 1 + 43% (Chrome 24) http://jsperf.com/jquery-child-selectors-ptan/2
  28. 28. Example 2 $(#target).find(p:first) querySelectorAll + getElementsByTagName + jQuery Extension
  29. 29. Example 2 $(#target).find(p:first-child) querySelectorAll
  30. 30. Example 2 $(#target).find(p).first() getElementsByTagName + .first()
  31. 31. Example 2 $(#target).find(p).eq(0) getElementsByTagName + .eq(0)
  32. 32. Example 2 $.fn.first = function() { return this.eq( 0 ); }; $.fn.first の中身
  33. 33. Example 2 + 87% (Chrome 24) http://jsperf.com/jquery-first-selectors-ptan/2
  34. 34. Example 3 $(#target).find(p[title="test"]) querySelectorAll
  35. 35. Example 3 $(#target).find(p).filter([title="test"]) getElementsByTagName + .filter()
  36. 36. Example 3 - 44% (Chrome 24) http://jsperf.com/jquery-attribute-selectors-ptan/2
  37. 37. キャッシュの活用も忘れずにvar $target = $(#target), $p = $target.find(p);$target.on(click, function(e) { $p.toggle();});
  38. 38. リフローの影響を考える
  39. 39. HTML DOM視覚部分を表すツリー レンダーツリー 描画 CSSOM CSS
  40. 40. CSS Reflow - jQuery.com
  41. 41. DOMツリー html head body title h1 p[text node] [text node] [text node]
  42. 42. レンダーツリー ツリーに挿入されない要素 root display:none head body title h1 p [text line] [text line] [text line]
  43. 43. レンダーツリー ツリーに挿入されない要素 root display:block head body title h1 p [text line] [text line] [text line] リフロー!レイアウトの計算を行う処理のこと
  44. 44. HTML DOMレンダーツリー 描画 CSSOM CSS
  45. 45. HTML DOM リペイント!JS レンダーツリー 再描画 CSSOM CSS
  46. 46. HTML$(p).css(margin, 5px) DOM JS レンダーツリー 再描画 CSSOM + リフロー CSS
  47. 47. HTML$(p).css(color, red) DOM JS レンダーツリー 再描画 CSSOM CSS
  48. 48. リフロー 2?$(p).css(margin, 5px)$(p).css(margin, 5px)
  49. 49. 1 位置変更がないため
  50. 50. リフロー 4?$(p).css(margin, 5px) .css(padding, 5px) .css(top, 5px) .css(left, 5px);
  51. 51. 1 可能な限り収束される
  52. 52. 収束が難しいケース$(p).css(margin, 5px) .css(padding, 5px) .css(top, $target.height()) .css(left, 5px);
  53. 53. 2 ...あれ?
  54. 54. 最近のChrome賢すぎ... photo by pedrosimoes7
  55. 55. 2 Safariでやります (スミマセン...)
  56. 56. リフロー?リペイントのみ?- display- visibility- opacity- border- border-radius
  57. 57. リフロー?リペイントのみ?- display- visibility リペイントのみ- opacity リペイントのみ- border- border-radius リペイントのみ
  58. 58. リペイントのみでもモノによっては高コスト- color: rgba()- opacity- background: linear-gradient()- border-radius- text-shadow- ... etc See also
  59. 59. リフローが発生する可能性のあるトリガー- CSSの変更/取得 css(), addClass(), show(), animate() ...- DOM要素の操作 html(), text(), append(), focus() ...- 特定のプロパティの取得 offset(), position() ...- ユーザー操作 ウィンドウサイズの変更, スクロール, テキストの入力 ... See also
  60. 60. 不要なリフローを避ける
  61. 61. Example 1 $(<p>test</p>).appendTo(body).hide(); 生成時に色々と追加が 必要なケース
  62. 62. Example 1 $(<p>test</p>).hide().appendTo(body); 描画する前に行う
  63. 63. Example 1 Before
  64. 64. Example 1 After
  65. 65. Example 2 $(<img src="200x100.jpg">). appendTo(body); imgを生成するケース
  66. 66. Example 2 $(<img src="200x100.jpg" width="200" height="150">). appendTo(body); 描画の領域を明示しておく CSSで指定しても×
  67. 67. Example 2 Before
  68. 68. Example 2 After
  69. 69. Example 3 $(p).css(top, $target.offset().top) .css(left, $target.offset().left); 複数回に分けて実行されるcss()
  70. 70. Example 3 $(p).css({ top: $target.offset().top, left: $target.offset().left }); 1回のcss()にまとめる
  71. 71. Example 3 $(p).css({ top: $target.offset().top, left: $target.offset().left }); リフローが必要な取得系メソッド
  72. 72. Example 3 var offset = $target.offset(); $(p).css({ top: offset.top, left: offset.left }); 可能ならキャッシュして使い回す
  73. 73. Example 3 Before
  74. 74. Example 3 After
  75. 75. Example 4 <script src="jquery.js"></script> <script src="jquery-ui.js"></script> <script> $(function(){ $(#target).accordion(...); }); </script> </body> UI表示後にスタイルを変更するケース
  76. 76. Example 4 表示 JS 変更 読み込み, パース, 実行... この間は待ち時間
  77. 77. Example 4 <script src="jquery.js"></script> <script src="jquery-ui.js"></script> <script> $(function(){ $(#target).accordion(...); }); </script> </head> <head> に移す
  78. 78. Example 4 JS 表示&更新
  79. 79. Example 4その他の代替案- スタイル付けはCSSでやる- async属性で非同期にする (IE10∼)- 既存の非同期ローダーに乗っかる (RequireJSとか)
  80. 80. ボトルネックを解消する
  81. 81. ボトルネックになりそうなところ- 描画コストの高いCSSプロパティ- アニメーション- ループ処理- scroll, resize などの発火回数の多いイベント- ... etc
  82. 82. Google Chrome Canary
  83. 83. jQuery Animations < CSS3 http://dev.opera.com/articles/view/css3-vs-jquery-animations/
  84. 84. requestAnimationFrame https://github.com/gnarf37/jquery-requestAnimationFrame
  85. 85. throttle / debouncehttp://ktkne.st/elab/post/2012/strcount-throttle-debounce.html
  86. 86. その他- スタイルの変更は出来るだけ末端要素で行う- アニメーションは固定配置にする- テーブルレイアウトをしない
  87. 87. 戒めのお言葉
  88. 88. 小さな効率は忘れよう。時間の97%について語ろう。早まった最適化は諸悪の根源だ。 Tony Hoare? photo by glingl
  89. 89. Thank you photo by Furryscaly

×