html5でアプリの壁を超える方法
今回の前提
- iOSの対象は4系以降
- Androidの対象は2.2以降
- 各OSの標準ブラウザのみ
その壁の向こうへ
HTML5とアプリの壁とは?
これらが重要であるならネイティブアプリと連携させる方が無難
しかしものによっては(一応)が道ついている
壁を超える方法
- 音楽
- 写真
- 動作速度
- デバッグ、UnitTest
- エフェクト
- 通信
音楽
制限
- 同時に再生できる音源は1ファイルのみ
- 再生できるタイミングはユーザイベントのハンドラ内だけ
- プリロード不可
- OS自体のサイレントモードと連動せず
BGMを流すだけならこんな方法も
$('<div>BGMを再生しますか?</div>').appendTo('body').click(function () {
$(this).remove();
(new Audio('bgm.mp3')).play();
});
$('body').on('click', 'a', function (e) {
e.preventDefault();
$.get($(this).attr('href')).success(function (html) {
$('body').html('');
$('body').append($(html).find('body'));
})
});
ユーザもブラウザから音が流れるのになれてないので使用には注意が必要
写真
制限
- JSからカメラAPIへのアクセスはAndroid4以降
- input[type="file"]はAndroid2.2以上かiOS6で動く(予定)
ファイルアップだけならAndroidのみHTMLで可能
機種によってはファイルアップ時にカメラでの撮影が可能
動作速度
制限
- iOS WebViewはJITが効かない
- そもそも遅い
では「どこが」遅いのか?
1. click event
スマホ系のブラウザはtouchendからclickまでの間に300ms程度の待ちがある
ダブルタップのイベント等のため
「WebViewが遅い」と言われるのは待ち時間が入っていることも
300msは体感できる速度
この待ち時間はJSの処理を見なおしても早くならない
2. jQuery
遅い機種はjQueryを読み込むと初期化時間が500ms程度増える
ダウンロードに200ms程度、初期化に300ms程度
もしjQueryを使うのであれば、JSでの画面遷移を推奨
jQueryMobileはこの方式だが、初期化時間はjQuery単体よりも長くなる
現状jQueryと初期化速度はトレードオフなのでどちらかを選択するしか無い
jQuery 2系ではこのへんの対応が入る
3. イベント
それ以外でもtouchmoveやscrollなど多発するイベントは適当に間引きする
4. その他
遅い場所がわからない場合Androidであればadb経由で内部情報が見える
(iOSの場合JB等が必要になる)
adbできること
- adb shellでコマンドラインが触れる
- adb logcatでGCのタイミングも
さらにAndroid4系の場合、標準で画面上にCPU使用率を表示させられる
ただし、PCと実機とでは傾向が違う場合もあるので一番は実機検証
デバッグ、UnitTest
壁ではあるが、他の壁よりは越えやすい
1. デバッグ
JS部分だけに限ればChromeでも大体の検証は可能
実機で検証する場合、iOSに関してはProxyでファイルを差し替えればそこまで難しくない
iOSはアプリ内WebViewでもProxy設定が使えるので検証は容易
Android2系はProxy設定ができないので実機デバッグが難しい
4系でも標準ブラウザ以外Proxy設定ができない
2. UnitTest
最近はブラウザ上のUnitTestも情報が増えてきたので、かなり壁は低くなっている
PCのコンソールからスマホ上でテストを走らせることも可能でかなり楽
ただし、ブラウザ自体の問題もあるのでどこまでテストするかは難しい
エフェクト
JSでのアニメーションは2、3要素同時が限界
CSSアニメーションなら4、5要素同時に動かせる
ただ、CSSアニメーションはAndroid2系でバグと未実装が多い
Android2系で検証しつつ追加するか、Android2で動かないエフェクトを切れる構成がおすすめ
通信
制限
- 1. ページ遷移
- 2. 通信エラー
- 3. キャッシュ
- 4. クロスドメイン
- 5. サーバサイドプッシュ
1. ページ遷移
通常の画面遷移の場合、一瞬背景が白くなる
これに関してはAjaxでhtmlを取得し、JSでページ要素を切り替えることで背景を保持した遷移が可能
$('body').on('click', 'a', function (e) {
e.preventDefault();
$.get($(this).attr('href')).success(function (html) {
$('body').html('');
$('body').append($(html).find('body'));
})
});
この方法はjQueryMobile等多くのフレームワークが採用しているのでこの前提で実装するのがおすすめ
2. 通信エラー
JSでのページを切り替え方式であればサーバとの通信エラーも取れる
「3回試行してだめならダイアログ表示」といった事も可能
3. キャッシュ
JSでのページを切り替え方式であればキャッシュの制御も行いやすい
また、iOS, Android標準ブラウザはWebSQL(SQLite)が使える
localStorageもあるのでキャッシュ環境は結構リッチ
4. クロスドメイン
Android2系は公式にはクロスドメイン通信をサポートしない
Android2.3系では使える場合もあるが動きがおかしい場合もあるので注意
JSONPなどの古いIEと同じ対応が無難
5. サーバサイドプッシュ
WebSocket
- Proxyが設定されていると落ちる
- 4.1でChromeが標準になりサポート
サーバが30秒毎に空データを送信し、実データ送信後毎回切断して繋ぎ直せば動作可能
最後に
いいね!
ご清聴ありがとうございました!