angularとonsen uiで作る最高のhtml5ハイブリッドアプリ

Post on 15-Jul-2015

20.734 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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を採用

http://components.onsen.io/

- ウェブ上で簡単に色をカスタマイズできるテーマローラも完備

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を開発してくれるエンジニアを募集しています

ご清聴ありがとうございました

top related