Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

HTML5 Conference 2015 悩める組込機器向けウェブコンテンツのパフォーマンス

12 291 vues

Publié le

近年、ブラウザーやブラウザーランタイムは、PCやスマートフォンのみならず、テレビ、コンソールゲーム機などの組み込み機器にも導入されるようになりました。また、Raspberry Piに代表されるSingle Board Computer(SBC)も流行りだし、ロースペックな環境で動作しなければならないウェブアプリケーション開発の需要が高まろうとしています。

多くの組み込み機器に搭載されたは、近年よく使われるAPIやCSSをサポートしています。しかし、そのパフォーマンスはスマートフォンと較べて非常に貧弱です。スマートフォンでは当たり前のパフォーマンスが得られることはありません。

本セッションでは、組み込み向け機器の現状を紹介し、その上で動作するウェブアプリケーションの開発の課題、私の経験での苦労話、そして、それに立ち向かうための Tips を紹介します。

Publié dans : Technologie
  • Soyez le premier à commenter

HTML5 Conference 2015 悩める組込機器向けウェブコンテンツのパフォーマンス

  1. 1. 悩める組込機器向けウェブコンテンツのパフォーマンス 2015年1月25日 HTML5 Conference 2015 @futomi futomi.hatano
  2. 2. もくじ • 組込機器とブラウザー • 組込機器ブラウザーの問題 • パフォーマンスの定義 • ページのロード • ペイント領域とGPUメモリー • 画像のロード • ビデオのロード • メモリー消費 • prototype • DOMアクセス • まとめ
  3. 3. 組込機器とブラウザー
  4. 4. SBC (Single Board Computer) Raspberry Pi B+ BeagleBone Black ODROID-U3 ODROID-C1 Cubieboard 1/2 Marsboard RK3066 Radxa Rock Lite HummingBoard i1/i2 Banana Pi KDDI Open Web Board
  5. 5. 貧弱なCPUと少ないメモリ SONY Xperia Z3 Qualcomm Snapdragon 801 CPU: 4 Core (2.5GHz) RAM: 3GB Raspberry Pi B+ Broadcom BCM2835 CPU: 1 Core (700MHz) RAM: 512MB Cubieboard 2 Allwinner A20 CPU: 2 Core (1GHz) RAM: 1GB HummingBoard i1 Freescale i.MX6 Solo CPU: 1 Core (1GHz) RAM: 512GB Alcatel One Touch Fire Qualcomm Snapdragon MSM7227A CPU: 1 Core (1GHz) RAM: 256MB 近年のスマートフォンは超贅沢品
  6. 6. 組込機器ブラウザーの問題
  7. 7. テレビブラウザーの系統 スマートフォン向けブラウザー事情に酷似 ウェブアプリ開発の環境が整う
  8. 8. バージョンが固定 • なかなかブラウザーは更新されない • 機器のライフサイクルが長い • 古いバージョンが長期間残り続ける • いつか勝手に解決するとは思っては いけない... http://www.bbc.com/news/technology-20957218
  9. 9. 貧弱なCPUと少ないメモリー • 処理時間オーバー • スマートフォンではサクッと終わる処理がなかなか終わらない • アルゴリズムを考え直すか、分割して処理する必要がある • メモリーリーク • スマートフォンでは気にならなかったメモリーリークがすぐに顕在化 • JSによるメモリーのお漏らしは厳重にチェックする必要がある • ブラウザーのバグが顕著に出る • 組込機器はCPUが貧弱でメモリが少ないため、PCやスマートフォン では顕在化しない問題が起こる
  10. 10. パフォーマンスの定義
  11. 11. パフォーマンスとは • 速く • 起動を速く • 処理を速く • アニメーションを滑らかに • 少なく • メモリ消費を少なく • CPU処理を少なく • 長く • 安定動作を長く
  12. 12. パフォーマンスとは • 速く • 起動を速く • 処理を速く • アニメーションを滑らかに • 少なく • メモリ消費を少なく • CPU処理を少なく • 長く • 安定動作を長く すべてをかなえてくれる魔法の杖は...
  13. 13. パフォーマンスとは • 速く • 起動を速く • 処理を速く • アニメーションを滑らかに • 少なく • メモリ消費を少なく • CPU処理を少なく • 長く • 安定動作を長く すべてをかなえてくれる魔法の杖は... ありません!!!
  14. 14. パフォーマンスとは • 速く • 起動を速く • 処理を速く • アニメーションを滑らかに • 少なく • メモリ消費を少なく • CPU処理を少なく • 長く • 安定動作を長く すべてをかなえてくれる魔法の杖は... ありません!!! 何を捨てるのか、 何を諦めるのか、 を決めるのも重要 しかし、 ちょっとした配慮で パフォーマンスを改善
  15. 15. ページのロード
  16. 16. ネットワーク処理は高コスト • ダウンロードサイズとファイル数は少ないほど良い • HTML/CSS/JavaScriptのMinify • 極端に言えば、すべてHTMLにインラインに埋め込むのがベスト • パフォーマンスと保守性のバランスを考えましょう • 極度にMinifyツールを使うとJSが動作しない場合も • CSS Spriteもほどほどに
  17. 17. Google Closure Compiler https://developers.google.com/closure/compiler/
  18. 18. ペイント領域とGPUメモリー
  19. 19. Chromeデベロッパーツール 1 2 3 ペイント領域 FPS meter
  20. 20. ペイント領域とGPUメモリー • 一般的に良く言われる手法 • ペイント領域は可能な限り小さく • GPUアクセラレーションが有効な環境ならレイヤーを活用 • 動かすだけなら JavaScript のタイマーによる位置移動は避ける • CSS Transitions と CSS Transforms の活用 • 組込デバイスだと • GPUメモリーの上限が低い • レイヤー活用は必要最小限に • ペイント領域を可能な限り小さくするのは言うまでもない
  21. 21. コンテンツの移動 setTimeout() と left プロパティによるアニメーション CSS Transitions と CSS Transforms の translateX() によるアニメーション 移動のたびにペイント処理が実行され不効率 レイヤー処理により移動がスムーズかつGPUメモリー消費が少ない
  22. 22. レイヤーの使いすぎに注意 • 組込機器のGPUメモリーはさほど多くない • メインメモリーやGPUメモリーの速度もネックになる • 特にフルHDなど広い解像度を扱うコンテンツでは要注意 • 使いすぎると返って不効率
  23. 23. 値のリアルタイム更新 <p>経過時間: <span id="t">0</span> ミリ秒。</p> var el = document.querySelector("#t"); (function countUp(now) { el.textContent = Math.round(now); window.requestAnimationFrame(countUp); })(); 数値のみを書き換えているのに、 行全体が再ペイント JS
  24. 24. 値のリアルタイム更新 <p>経過時間: <span id="t">0</span> ミリ秒。</p> var el = document.querySelector("#t"); (function countUp(now) { el.textContent = Math.round(now); window.requestAnimationFrame(countUp); })(); 数値のみを書き換えているのに、 行全体が再ペイント JS
  25. 25. 浮かせる/サイズを固定する <p>経過時間: <span id="outer"><span id="t">0</span></span> ミリ秒。</p> var el = document.querySelector("#t"); (function countUp(now) { el.textContent = Math.round(now); window.requestAnimationFrame(countUp); })(); #outer { display: inline-block; width: 100px; height: 20px; position: relative; } #t { display: inline-block; width: 100px; position: absolute; text-align: right; } JS CSS
  26. 26. 表示と非表示の切替 <body> <img id="logo" src="imgs/logo.png"> <footer>...</footer> </body> var el = document.getElementById("logo"); var hidden = false; window.setInterval(function() { hidden = !hidden; el.style.display = hidden ? "none" : "block"; }, 1000); ロゴしか切り替えていないのに リフローの発生よりページ全体が 再ペイントの対象に 実際に見た目にリフローがなくても、 ブラウザーは再レンダリングを 行おうとしてしまう。 JS
  27. 27. CSSで位置固定 #logo { position: absolute; } <body> <img id="logo" src="imgs/logo.png"> <footer>...</footer> </body> var el = document.getElementById("logo"); var hidden = false; window.setInterval(function() { hidden = !hidden; el.style.display = hidden ? "none" : "block"; }, 1000); JS CSS
  28. 28. 画像のロード
  29. 29. img要素のloadイベント http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element HTML5仕様曰く: If the download was successful and the user agent was able to determine the image's width and height, [...] fire a simple event named load at the img element. ダウンロードが成功し、ユーザーエージェントが画像の幅と高さを判定できたら、 [...] img要素で load という名前のシンプルなイベントを発出します。 loadイベントはレンダリング完了を表しているわけではない 組込機器では、loadイベントの発生と、実際にレンダリングが完了した タイミングの差が大きく出る
  30. 30. 巨大な画像のロード直後の処理 • img要素のloadイベント発生直後に重い処理をするとペイント処理とか ぶってしまいブラウザーが固まる場合がある • ペイントが完了したというイベントは取れない • 手を抜くなら、こうするしかない... imgElement.onload = function() { window.setTimeout(function() { // 何か次の処理 }, 100); }; JS
  31. 31. ビデオのロード
  32. 32. 組込機器には大敵なビデオデータ • 再生開始タイミングのパフォーマンスを気にするなら <video preload="auto"> • たとえ再生されなくてもバッファリング分のメモリーを消費 • 複数のビデオを事前に用意するのは厳しい • メモリーにやさしい方法を選ぶなら <video preload="none"> • 再生開始のタイミングがかなり遅れる • どうしても事前にビデオの寸法と尺を知りたいなら <video preload="metadata">
  33. 33. MP4の再生開始パフォーマンス • ファイルの最後にメタ情報が格納されている • これによって再生開始が大幅に遅れる • ブラウザーの挙動 1. ファイルの先頭を読み取る 2. メタ情報がないと判定し、ファイルの末尾を読み取る 3. ファイルの先頭に戻ってバッファリング分のビデオデータをダウンロードする
  34. 34. • エンコード時にFast Startを有効にする • メタ情報がファイルの先頭にセットされる • ブラウザーの読み取り回数が1回で済む • 再生開始パフォーマンスが向上する Fast Start
  35. 35. メモリー消費
  36. 36. メモリーリークの確認 Heap、Documents、Nodes、Listenersすべての推移の確認が重要
  37. 37. ノコギリ型のメモリー消費 • ガベージコレクションは負荷が高いためアニメーションを妨げる • 一般的にノコギリ型のメモリー消費は良くないと言われるが、それはデバ イス環境とユースケース次第 • メモリーが少ない環境では、早めにガベージコレクションを発生させ、 ピークを抑えるほうが良い場合もある
  38. 38. prototype
  39. 39. prototypeを使わない場合 var MyWallet = function(init_price) { this.price = init_price; this.earn = function(price) { this.price += price; if(this.price > 1000) { this.pay(this.price - 1000); } }; this.pay = function(price) { this.price -= price; }; this.look = function() { return this.price; }; }; JS
  40. 40. prototypeを使った場合 var MyWallet = function(init_price) { this.price = init_price; }; MyWallet.prototype.earn = function(price) { this.price += price; if(this.price > 1000) { this.pay(this.price - 1000); } }; MyWallet.prototype.pay = function(price) { this.price -= price; }; MyWallet.prototype.look = function() { return this.price; }; JS
  41. 41. メモリー消費に違いが出る(極端な例) var list = []; for( var i=0; i<100000; i++ ) { var w = new MyWallet(0); list.push(w); } prototypeを使わない場合 prototypeを使った場合 62MB 32MB JS
  42. 42. DOMアクセス
  43. 43. JavaScriptライブラリー • 使わない機能もテンコ盛り • 使わなくてもメモリーに展開されてしまう • できる限り機能を限定したライブラリーが良い • おすすめのJSライブラリーは...
  44. 44. http://vanilla-js.com/
  45. 45. 全機能にチェックを入れても、gzipでたったの25バイト 展開したら、なんと0バイト
  46. 46. みなさん、もうお気づきですね Vanilla JS はジョークサイトです DOM 操作は素で書くのが最もパフォーマンスに優れます
  47. 47. まとめ
  48. 48. • 流行りのライブラリーやプログラミング手法が良いとは限らない • メモリーが潤沢な環境を前提としていないかを考えるべき • レガシーな手法も見直そう • メモリーが少ない時代に考えられた手法は今なお組込デバイスでは有効
  49. 49. ご清聴ありがとうございました @futomi futomi.hatano

×