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

13,720 views

Published on

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

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

Published in: Technology
0 Comments
77 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
13,720
On SlideShare
0
From Embeds
0
Number of Embeds
233
Actions
Shares
0
Downloads
0
Comments
0
Likes
77
Embeds 0
No embeds

No notes for slide

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

×