HTML5ハイブリッド
アプリ開発の実践
開発現場ですぐに活かせるコツを伝授!
2014年4月24日(木)
久保田光則
‣ アシアル株式会社所属
‣ UI/UXデザイナー兼エンジニア
‣ ハイブリッドアプリ開発や

monaca開発に携わる
2
今日話すこと
今日話すこと
‣ HTML5ハイブリッドアプリって何?
‣ 開発で使えるノウハウ・テクニック
4
HTML5ハイブリッドアプリって何?
アプリの種類
6
Java
or
Objective-C
アプリ アプリ
ネイティブアプリ ハイブリッドアプリウェブアプリ
ネイティブアプリ
‣ いわゆる「普通のアプリ」
7
Java
or
Objective-C
Java
or
Objective-C
アプリ
ウェブアプリ
‣ ブラウザ上で動くアプリ
‣ 要するにウェブページ
8
HTML5ハイブリッドアプリ
‣ ウェブ技術+ネイティブのハイブリッド
9
アプリ
ネイティブ層
HTML5
仕組み
‣ アプリ内にWebViewを表示
‣ WebViewはパッケージ内のHTMLを読み込み
10
アプリ
HTML
読み込み
WebView
クロスプラットフォーム性
11
Android iOS
ウェブ技術が使える
‣ 馴染みのあるウェブ技術で開発できる
‣ ウェブ技術のエコシステムを利用できる
12
ストアで配布できる
‣ いわゆる「普通のアプリ」と同じように配布できる
‣ ブラウザを立ち上げる必要なし
13
まとめ
‣ HTML5ハイブリッドアプリは、

ネイティブとウエブの良い所を取り入れている
14
Java
or
Objective-C
アプリ
アプリ
ハイブリッドアプリ
疑問
‣ どうやって埋め込んでる?
15
?
アプリ
ネイティブ層
HTML5
PhoneGap
PhoneGap(Cordova)
17
‣ ハイブリッドアプリのためのフレームワーク
‣ monaca内部でも利用
‣ 他にはTriaina、Trigger.ioなど
PhoneGapの役割
18
‣ HTML5をアプリとして包み、HTML5側とOS側を繋ぐ
アプリ
OS API
PhoneGap
JavaScriptから
OSネイティブの機能が使える
19
Android / iOS
API
PhoneGapの提供API
20
‣ PhoneGapプラグインの

仕組みを使えばこれ以外のことも可能
ファイルストレージ、カメラ、コンパス
加速度センサー、コンタクトリスト、
位置情報取得、ネットワーク、Bluetooth通信、
Androidのインテント、アプリ内ブラウザ、
GPS、NFC、etc…
テクニック・ノウハウ
実際に開発を始めると
様々な問題が…
22
よくある問題
‣ 描画や動作が遅い
‣ アプリっぽくならない
23
クリックイベントを使わない
24
‣ a要素やclickイベントは300ms遅延が発生
‣ tappableやfastclick使いましょう
clickイベント
a要素
touchイベントで処理
CSSアニメーションを使う
25
‣ アニメーションにCSS Transitionを使う
‣ JavaScriptで直接やるよりはるかに速い
‣ setIntervalでアニメーションするのを置き換える
すぐわかるCSS Transition
26
.foobar {
background-color: white;
}
.foobar:hover {
-webkit-transition: background-color 1s linear;
background-color: red;
}
.foobarクラスの要素 .foobarクラスの要素
jQueryではなくZepto.js使う
27
‣ zepto.jsはモバイルに最適化
‣ jQueryの互換APIを提供
動作確認は遅い方に合わせる
28
‣ WebViewはAndroidよりもiOSの方がはるかに速い
‣ 動作確認は遅い方のプラットフォームに合わせる
‣ 後からチューニングして修正するのは大変
1. 2. iOS
なるべくリフローを起こさない
29
‣ DOMツリーのレイアウトの再計算
‣ リフローするごとに、

画面全体のレイアウトの再計算処理が走る
レンダリングの仕組み
30
‣ DOMツリーとCSSをパース
‣ レイアウトを計算した後レンダリング
‣ リフローとは、レイアウトの再計算処理
CSSルール
DOMツリー
レイアウト
計算
描画
何がリフローを引き起こす?
31
‣ 内部テキストの変更、input要素への入力
‣ DOMツリーの操作
‣ width, height, margin, padding, border等の変更
‣ クラス属性やスタイルシートの変更も含む
?
リフローのコストを

抑えるのも重要
32
‣ アプリのインタラクションにDOM操作は必須
‣ どうしてもリフローは起きる場合がある
‣ リフローのコストを下げる
リフローのコストを下げるには?
33
コストを下げる
‣ リフローが重いとどうなる?
‣ インタラクション・画面更新が遅くなる
要素の縦横を固定する
34
‣ リフロー時のコンテナの計算を抑制
100%
30px
.foobar {
width: 100%;
height: 30px;
}
position: absoluteを多用する
35
‣ フローベースのレイアウトを使わない
‣ absoluteでレイアウトの計算を抑制
40px
30px
.foobar {
position: absolute;
left: 40px;
top: 30px;
}
transformを使う
36
‣ marginやpaddingや要素サイズ変更 => リフローを引き起こす
‣ その代わりにtransformを使う => リフローを引き起こさない
.foobar {
-webkit-transform: translate(20px, 10px);
}
transformを使う
37
‣ marginやpaddingなどを変えるとリフローを引き起こす
‣ その代わりにtransformを使う => リフローを引き起こさない
.foobar {
-webkit-transform: translate(20px, 10px);
}
リフローを確かめる
38
‣ Chromeのインスペクタを利用
‣ Timelineタブより計測
リフローを伴う
アニメーションをさせない
39
‣ CSSアニメーションでもリフローを起こすと遅くなる
‣ リフローを起こすアニメーションを避ける
‣ -webkit-transformを使う
GPUを活用する
40
.foobar {
-webkit-transform: traslate3D(0px, 0px, 0px);
}
‣ 特定の要素をGPUで描画する
‣ transitionアニメーションに効果大
DOMDocumentFragments
を使う
41
‣ DOM要素をくりかえしDOMツリーに挿入しない
var fragment =
document.createDocumentFragment();
悪い例
42
var div = document.getElementsByTagName("div");
for (var i = 0; i < div.length; i++) {
for (var e = 0; e < elems.length; e++) {
div[i].appendChild(elems[e].cloneNode(true));
}
}
繰り返しDOMツリーに挿入
http://ejohn.org/blog/dom-documentfragments/ より引用
DocumentFragmentsの例
43
var div = document.getElementsByTagName("div");
var fragment = document.createDocumentFragment();
for (var e = 0; e < elems.length; e++) {
fragment.appendChild(elems[e]);
}
for (var i = 0; i < div.length; i++) {
div[i].appendChild(fragment.cloneNode(true));
}
最後に一度だけDOMツリーに挿入
http://ejohn.org/blog/dom-documentfragments/ より引用
まとめ
44
‣ アプリとして軽快に動作する必要あり
‣ 最適化のテクニックを把握しておくことが重要
Onsen UIについて
‣ http://onsenui.io
Onsen UI
‣ ハイブリッドアプリ用UIフレームワーク
‣ Angular.jsベース
‣ 画面遷移の管理やUIコンポーネントを提供
‣ http://onsenui.io
47
48
‣ monaca上ですぐに利用可能
その他UIフレームワーク
‣ jQuery Mobile
‣ Sencha Touch
‣ Ionic
‣ Kendo UI
49
好評発売中!
50
‣ ハイブリッドアプリ開発の包括的な知識を解説
ご清聴ありがとうございました

HTML5ハイブリッド アプリ開発の実践〜開発現場ですぐに活かせるコツを伝授〜