Download - AngularとOnsen UIで作る最高のHTML5ハイブリッドアプリ
Angularと Onsen UIで作る 最高のHTML5 ハイブリッドアプリ
ng-japan 2015年3月21日 アシアル株式会社 久保田光則
久保田光則
- @anatoo - アシアル株式会社所属 - UI/UXデザイナー兼ソフトウェアエンジニア
- Onsen UIリード開発者
好評発売中!
- 最近になって韓国語版も翻訳出版されます
話すこと
Onsen UIテーマ:
http://onsen.io
Onsen UI
- HTML5ハイブリッドアプリ用のUIフレームワーク - Angularをベースにしています - iOS, Androidをサポートしています - 高速な動作性がウリです - なんてことを説明しててもつまらないですよね。
本当に話すこと
- HTML5ハイブリッドアプリとは?
- ハイブリッドアプリ開発にどんな問題があるのか?
- なぜAngularとOnsen UIが必要なのか?
- 少しだけOnsen UIの紹介
HTML5ハイブリッドアプリとは
ネイティブアプリ
- Objective-CやJavaなど、そのOSの流儀で実装 - いわゆる普通のアプリ
Java or
Objective-CJava
or Objective-C
アプリ
ウェブアプリ
- ブラウザで動作する - 要するにただのウェブページ
HTML5ハイブリッドアプリ
- アプリとして動作 - 内部の実装にHTML5をつかっている
アプリ
ネイティブ層
HTML5
仕組み
アプリ
HTML
読み込み
WebView
HTML5ハイブリッドアプリの 何が良いのか?
クロスプラットフォーム性
Android iOS
ウェブの知識が活かせる
ストアでの配布
- 外見は普通のアプリなので、ストアで配布可能
ネイティブの機能の呼び出し
Android / iOS
OS API
Cordovaについて
- ハイブリッドアプリ用フレームワーク - 昔はPhoneGapという名前だった
http://cordova.apache.org
Cordovaがやってくれること
- HTML5をアプリ内部にパッケージ化 - OSとのAPIのやり取りを一本化
Cordovaの提供するプラグイン
‣ さらにCordovaプラグインの仕組みを使えばこれ以外のことも可能
ファイルストレージ、カメラ、コンパス 加速度センサー、コンタクトリスト、 位置情報取得、ネットワーク、Bluetooth通信、 Androidのインテント、アプリ内ブラウザ、 GPS、NFC、etc…
「HTML5でモバイルアプリが作れるんですね、やったー」
こうして数多くのフロントエンド開発者が
HTML5ハイブリッドアプリに
取り組んでいくことになった…
結果
- 数年程度前の出来事 - いったいなにが起こった?
最も有名な失敗例
「HTML5に賭けたのは失敗」Facebook ザッカーバーグCEO
- HTML5で記述したfacebookアプリをネイティブで書きなおす
2012年9月11日 TechCrunch Disrupt SF 2012より
数年前に比べて現在状況は 好転してきた
- 端末スペックの向上 - CPU、メモリ共に一昔前のノートPCとほぼ同じに
- AndroidでのWebViewのChromiumの採用 - 利用できるHTML5 APIの増加 - Android2.3系のシェアの低下 - CrossWalkの登場 - Android5からのAndroid System WebViewの導入 - HTML5ハイブリッドアプリの事例の増加 - BYODの一般化により
好転を表すシグナル
- Rails作者のDHHによるHTML5ハイブリッドアプリ評
しかしそれでも
- HTML5ハイブリッドアプリは遅い!
- ネイティブに比べると 使い物にならない!
- 昔の体験が・・・
画像出典: ヒストリエ
問題
直接の問題
- パフォーマンスや安定性が悪い - UIコンポーネントをいちいち作らないといけない
パフォーマンスに関する答え
チューニングすればいいじゃん!
- 今ではハイブリッドアプリは十分速く動作する
- だから勝手にチューニングすればいい、と思ってた
得られた知見
- フロントエンド開発者の多くは、HTML・CSS・JSの書き方だけしかわかっていないことがわかった
- 多くの開発者はより素早く描画するためのチューニング方法を知らない
レンダリングの仕組み
効率的なチューニング
- まずは、どこがボトルネックになっているのかを知る - インスペクタのTimelineタブで計測 - AndroidではChrome、iOSではSafariのインスペクタを利用
- インスペクタのTimelineタブで計測 - AndroidではChrome、iOSではSafariのインスペクタを利用
インスペクタのTimelineタブで取れるカテゴリ
Loading
Scripting
Rendering
Painting} 1frame
描画が始まって終わるまでが1frame これを16ms以下に抑えれば最高
ボトルネックがどこにあるかでチューニングもまた変わってくる
1. Loading
- リソースの読み込みやパース - ハイブリッドアプリではウェブアプリよりもここが消費する時間は短い - リソースがローカルにすでにあるから
2. Scripting
- JavaScriptの実行時間 - 純粋な計算は速い。基本的に問題にならない。 - ただし、canvasへの描画やディスクI/Oが発生したりリフローを同期的に強制するコードなどは遅い
Scriptingがボトルネックだったら?
- 話は簡単 - Profilesタブでさらにどのコードが重いのかを見る
- Bottom UpのSelf欄が重要
3. Rendering
- Rendering - レイアウト処理
- Recalculate Style - 要素に当たるCSSルールの計算 - Layout - Render Treeの生成
Recalculate Style - 要素のスタイルの計算
- 個別のDOM要素に対して、当たるスタイルを計算する
- CSS OMを参照して、DOM要素の数 x CSSルールの数分マッチング処理が走る - 重たいCSSの書き方を減らす - 使っていないCSSのルールは消す
Layout - RenderTreeの生成
- 全てのDOMのレイアウト情報を計算 - 計算された結果の視覚的なオブジェクトのツリーがRenderTree
4. Painting
- Painting - 描画処理 - Paint - Display List(ChromiumだとSkiaへの命令)の生成
- Rasterize - Display Listの実行してピクセル化 - Composite Layers - レイヤの合成
雑多なチューニングテクニック小話
translate3d(0, 0, 0)が速いのはなぜ?
- GPUで描画されるから?
- 半分正解だが半分間違っている - transform CSSプロパティを変更しても、Composite Layersのみが起こるから
- つまり、同時に別処理でLayoutを引き起こしたりすると台無し
どのCSSプロパティを変更すると何が起こる?
- 要素の大きさが変わるような場合Layoutから処理が始まる
- transformやopacityだとComposite Layersのみ走る - CSSプロパティによって変更で何が起こるか違う
- 詳しくはCSS Triggersでググるんだ!
DOMリークを防ぐ
- DOM要素が誤って参照されたまま開放されない - 見た目よりも深刻
- detached DOMツリーとそれに参照されているリソースが全てリークする
- iOS, Androidだとメモリスワッピングが弱く設計されている
reflowを起こさないようにする
- 画像のサイズは必ず指定する - 一度DOMツリーから切り離して操作する - offsetHeightやgetBoundingClientRect()を呼び出しつつstyleを変更するみたいなコードをループで書くと地獄
GPUバウンド
- CPUよりもGPUの方で時間がかかっている状態 - Rasterize後にテクスチャとしてGPUのVRAMに転送 - Composite Layers
- GPUへの転送や合成がCPU時間よりも時間がかかっていればGPUバウンド
GPUバウンドなページを作る
- 大きな領域を持つ要素にtransform: translate3d(0, 0, 0)を当ててたくさん生成してアニメーションさせる
- Rasterize時にGPUにテクスチャとして転送される - 転送や合成に時間がかかるようになる - GPUのVRAMへのbandwidthが分かれば転送にかかる時間の理論値が割り出せる
省略
- スライドが150ページ超えそうなので省略。
チューニングの罠
ただし
- こういったチューニングの大部分はレンダリングエンジンの実装に依存している
- どうしてもわからない時はWebKitやChromiumのコードを読むしか無い
ふと我に帰る瞬間
- なぜ単にHTML5でアプリ書きたいだけなのに私はChromiumのコードを読んでいるのか?
- なぜ単にCSS書いてるだけなのに私はGPUのVRAMへの転送速度を気にしなければならないのか?
- ここまでチューニングする余裕がアプリ開発中にあるのだろうか?
- こういったチューニングを全て把握することを全ての開発者に求めて良いのだろうか?
否!!
何かがおかしい
- ごく一部の人間でないと高速なHTML5ハイブリッドアプリは開発できないのだろうか?
- ユーザがアプリの構築そのものにフォーカスできないのだろうか?
ハイブリッドアプリ開発から見た 今のHTML5の課題
- アプリケーションアーキテクチャの構築方法の不在 - チューニングされて高速に動作するUI基盤が無い
?
iOS
UIKit
アプリ
Objective-C/Swift
Android
View System
アプリ
Java
iOSアプリ Androidアプリ
ネイティブだとUIフレームワークがある
- そのOSに必要なUIが全て揃っている - 開発者はUIフレームワークが裏で何をやっているか気にしなくても良い
- すぐにアプリを開発し始められる
- これに対してHTML5ハイブリッドアプリでは?
WebView&Cordova
!
アプリ
iOS/Android
HTML5ハイブリッドアプリ
- アプリの開発者が何もかも考えなければならない!
リストビューはどうやって実装すれば?
画面遷移の管理はどうすれば?
ジェスチャを扱うにはどうすれば良い?
MVCフレームワークには何を使おう?
アプリが遅いけどチューニングってどうやるの? CSSは最初から書いていく?
iOSのSwitchってどうやって実装するの?
viewportの設定ってどうやればいいの?
DOMの数が巨大になるとどれぐらい重くなるんだろう?
Bootstrapって使っていいのかな?
リストビューはどうやって実装すれば?
CSSの設計規約って何がいいのかな?fpsはどれぐらいを目標にすればいいんだろう?
描画の速度ってCIやテストで回せるっけ?
無いもの
- 使うだけで高速に描画されるUIキット - アプリケーションアーキテクチャを形作るもの
Onsen UI
- 開発者が、アプリの開発そのものにフォーカスできるようにする。
Angularをベースにして構築
- HTMLを拡張して、アプリも記述可能にしてくれる - 大規模なアプリでも耐えられるアーキテクチャ
- DIコンテナ、サービス、コントローラ、フィルタ等
Custom Elements
- HTMLを記述するだけでUIを構築できる
<ons-page class=“first-page”> <ons-toolbar>
<div class=“center”>Toolbar Title</div> </ons-toolbar> <div>
<p>Page Contents</p> <ons-button ng-click=“foo()”>
MyButton </ons-button>
</div> </ons-page>
CSSによるテーマ
- Adobeの超高速CSSフレームワークtopcoatをベースに構築 - CSSメタ言語にStylusを利用 - 設計規約はBEMを採用
Onsen UIのコンポーネント群
- チューニングにより高速に動作
ons-navigator
- 画面遷移と遷移アニメーションを管理する
<ons-navigator class=“first-page”> <ons-toolbar>
<div class=“center”>Toolbar Title</div> </ons-toolbar> <div>
<p>Page Contents</p> <ons-button ng-click=“foo()”>
MyButton </ons-button>
</div> </ons-navigator>
- ページをスタックで管理する - 画面遷移を司るコンポーネント
page1.html
page2.html
page1.htmlpushPage() popPage()
page1.html
ons-pull-hook
- いわゆるpull-to-refreshを実装できるコンポーネント
<ons-page> <ons-pull-hook ng-action="load($done)"> Pull to refresh </ons-pull-hook> <ons-list> ... </ons-list> </ons-page>
- pull-to-refreshの例
ons-lazy-repeat
- 数千数万のDOM要素のライフサイクルを管理 - いわゆる無限リストが簡単に実装できる
<ul> <li ons-lazy-repeat=“lazyRepeatDelegate”> … </li> </ul>
- 画面に必要な分だけ表示するので高速 - AndroidやiOSのリストビューと同等のことが可能
隠れたら アンロード
表示しそうなら ロード
ons-sliding-menu要素
- スライディングメニュー、ドロワーメニューを表現
ons-alert-dialog要素
- HTMLで表現されたアラートダイアログ
ons-popover要素
- 吹き出しを表現するコンポーネント
ons-carousel要素
- 置くだけでカルーセルのUIを表現
Onsen UIが目指すもの
- だれでもHTML5で高速に動作するモバイルアプリを作ることができる世界
- UIをどのようにチューニングするか、ではなくアプリの本質的機能の開発にフォーカスするための基盤
Onsen UI 2.0
- Material Designsサポート
- Angular2サポート
最後に
開発者募集
- アシアル株式会社では一緒にOnsen UIを開発してくれるエンジニアを募集しています
ご清聴ありがとうございました