SlideShare a Scribd company logo
実践的な

モバイルHTML5テクニック
Takuo KIHIRA
2013-11-30
2

自己紹介
• 紀平 拓男(きひら たくお)
– 株式会社ディー・エヌ・エー
– HTML5 Chief Engineer
– @tkihira

• 会社を2つ設立したシリアルアントレプレナー
• HTML5によるFlash Runtime『ExGame』を製作
• DeNAにおいてHTML5の総括を担う

• 「インストール」が大嫌い。インストールの無い世
界にしたい
Broadtail Confidential

Confidential
2
3

今回お話しする内容

今出来ること

将来出来ること

モバイル
ブラウザ

PCブラウザ

Broadtail Confidential

Confidential
3
4

なぜ今、
モバイルHTML5なのか

4
5

モバイルの現状を、真摯に受け止める
• 世の中、ネイティブアプリ全盛期
– パズドラからgmailまで、あらゆるアプリがネイティブアプ
リで登場
– HTML5で作成され、世界的に普及しているWebアプリは一つ
もない

• ネイティブアプリの開発が大変楽になっている
– メジャーなOSが、iOSとAndroidの2種類のみ
– クロスプラットフォームなフレームワークもたくさん出来
ている

• 大変遺憾ながら、
ネイティブアプリ >>> Webアプリ

Broadtail Confidential

Confidential
5
6

Webアプリの利点と欠点

利点

欠点

• インストールが不要

• 実行速度が遅い

• あらゆるブラウザ搭載端末か
ら、URLのみで起動できる

• 互換性がない

• リアルタイムアップデートが
可能

• 3D、音楽などのハードウェア
に密着した処理が辛い

• 欠点が大いに目立つ
– 作るのにコストがかかって本当に大変。エンジニアもあま
りいない

• しかし、皆様にはぜひとも、利点に目を向けて頂き
たい
Broadtail Confidential

Confidential
6
7

モバイルWebアプリのメリット
誰かと一緒に
プレイしたく
なり
ツイッターで
拡散する

まずゲームをプレイする

よくてスクリーンショット、大抵はAppStore直送

友人がツイー
トを確認して
URLをクリッ
クする
Broadtail Confidential

Confidential
7
8

モバイルWebアプリのメリット
誰かと一緒に
プレイしたく
なり
ツイッターで
拡散する

まずゲームをプレイする

友人の現在のプレイが即座にそのまま見られる!

友人がツイー
トを確認して
URLをクリッ
クする
Broadtail Confidential

Confidential
8
9

モバイルWebアプリのメリット
• 格闘ゲームのコンボ

• 「シムシティ」「A列車で行こう」の街

• 最近だと、姓名判断アプリがバズった
– ボタン一つで手軽にシェアできる
– URLをタップするだけですぐに確認できる
– シェアされた人がすぐに自分も体験できる

アプリでは、実現できない
Broadtail Confidential

Confidential
9
まとめ:なぜ今、モバイルHTML5なのか

10

• ネイティブアプリでは実現できないメリットを活用
したい
– TwitterのURLをタップしたら、即座にアプリを起動
– 広告バナーをクリックしたら、即座にアプリを起動
– アプリの中からURLを発行して独自のシーンでアプリを起動

• 現在の最先端:Webアプリのデメリットを地道につ
ぶす
– 実行速度が遅い
– 互換性がない
– 3D、音楽などのハードウェアに密着した処理が辛い

• モバイルアプリをネイティブアプリに近づければ、
Webアプリ「ならでは」のメリットを活用したアプ Confidential
Broadtail
Confidential
10
リになる
11

モバイルHTML5の基礎

11
12

モバイルWebとPC Webの違い
• PC Webにはブラウザがそんなにない
– IE、Chrome、Firefox、Safari、Opera

• モバイルWebにはブラウザがもっとない
– Mobile Safari、Android Legacy Browser、Android Chromeくらい
– しかもその全てがWebkitベース

• なので対応がとても楽

…というのは大嘘!
Broadtail Confidential

Confidential
12
Androidの互換性問題

13

• Androidは、メーカーがある程度自由にソースをいじ
れる
– Androidは比較的オープンであり、各社が自社の端末にあわ
せて最適化したAndroidを搭載するのが一般的

• ブラウザのベンチマークスコアは、重要な差別化要
因
– ブラウザがぬるぬる動くことが競争力に繋がる

• 各ベンダーがブラウザのソースコードに手を加えて
最適化
– そしてバグを埋め込む
Broadtail
• 結果として、端末の数だけ独自ブラウザがある状況 Confidential
Confidential
13
残念なお知らせ

14

• Androidの対応は、IE6の対応より大変です

Broadtail Confidential

Confidential
14
15

CanvasとCSS
HTML5でリッチな表現を作るときに、主に2通りのやり
方がある

• Canvas
– HTML5のCanvasと呼ばれるお絵かき機能を駆使し、画面上の
全てのピクセルを自前で描画する方式
– ExGame、LWF、CreateJS、ImpactJS等

• CSS (+ DOM)
– 元々のHTMLの伝統的な形式であるDOMとCSSを駆使し、ブ
ラウザの助けを最大限利用しながら描画する方式
– Swiffy、Sencha、Bootstrap、jQuery mobile

Broadtail Confidential

Confidential
15
16

CanvasとCSSの利点と欠点
利点
• 互換性バグを踏みにくい

Canvas

• 細かい最適化を自力で頑張
ることが出来る

欠点
• 表示のためのコード量が大
変多くなる(真っ当な人間
の書くものではない)
• ブラウザのサポートが得に
くい

• デザイナーが慣れ親しんだ
形式
CSS + DOM

• ブラウザの高速化施策の恩
恵を受けられることが多い

• 互換性に大変問題が多い
• 細かい問題を自力で解決す
ることが出来ない

• 両方を使いわけるスタイルも普及しつつある

Broadtail Confidential

Confidential
16
17

CanvasとCSSのどちらを使うか
• ちょっとしたアプリを作るのであればCSSが適している
– デザイナー志向のツールの存在
• Sencha Animator、jQuery Mobile

– CSS自体の豊富な機能
• CSS Animations、CSS Transforms、CSS Filters

– ブラウザのコントロールにゆだねることが出来る
• フレームスキップ、非表示時の処理軽減

• 作りこんだアプリの場合はCanvasの方が優れる
– (CSSに比べれば)高い互換性
– いくつかのサポートツールの登場
– 全てを自前でコントロールすることが出来る

• CSSも実用に耐えうるようになりつつあるが、Canvasがま
だ主流
Broadtail Confidential

Confidential
17
18

Canvas Tech

18
19

オンメモリCanvasの利用
• 何度も描画に利用する部分をメモリ上に退避し、そ
れを描画に利用する
var img = document.getElementById("data");
var cache = document.createElement("canvas"); // キャッシュ用Canvas
cache.width = img.width * 2; cache.height = img.height * 2;
var cacheCtx = canvas.getCotext("2d");
cacheCtx.transform(2, 0, 0, 2, 0, 0); // 倍に拡大する
cacheCtx.drawImage(img, 0, 0); // キャッシュ用Canvasに書き込む
ctx.drawImage(cache, 100, 100); // キャッシュを使って描画する

– Offscreen Canvas, On Memory Canvas等と呼ばれる
– キャッシュを確保すればその分のメモリが消費される
– とくに複雑な描画をする場合には、いかに綺麗にキャッシ
ュに乗せるかが高速化のポイントになる

Broadtail Confidential

Confidential
19
20

画像やCanvasの描画(drawImage)
• Canvasに画像を描画する際、小数点の位置に描画し
ない
– 小数点の位置に描画すると、
• アンチエイリアシングがかかる(こともある)のでにじむ
• 描画のスピードが遅い
ctx.drawImage(img, x | 0, y | 0); // 座標を整数に整える

• 拡大、縮小をせずに描画する
– 拡大縮小は時間がかかるので、メモリに余裕があれば拡大
済・縮小済の画像を用意して対処する

Broadtail Confidential

Confidential
20
21

new Functionによるオーバーヘッドの削減(1)
• 同じ図形をパス(moveToやlineToなど)を駆使して描
画する場合、描画用のデータを毎回解析せず、最初
に文字列として関数を作成し、それを関数化するこ
とでオーバーヘッドを削減できる
var svg = "M 51.35 38.55 L 30.35 0 L 21 0 L 0 38.55 L 8.3 38.55"
+ " L 12.7 30.3 L 38.65 30.3 L 43.05 38.55 L 51.35 38.55"
+ " M 34.9 23.5 L 16.5 23.5 L 25.7 6.45 L 34.9 23.5".split(" ");
var body = "ctx.beginPath();";
for(var i = 0; i < svg.length; i+=3) {
var pos = svg[i + 1] + "," + svg[i + 2];
if(svg[i] == "M") { body += "ctx.moveTo(" + pos + ");"; }
if(svg[i] == "L") { body += "ctx.lineTo(" + pos + ");"; }
}
var func = new Function("ctx", body + "ctx.fill();");
func(ctx);

Broadtail Confidential

Confidential
21
22

new Functionによるオーバーヘッドの削減(2)
• 生成されるJavaScriptはこんな感じ
ctx.beginPath();ctx.moveTo(51.35,38.55);ctx.lineTo(30.35,0);ctx.lineTo(21,0);
ctx.lineTo(0,38.55);ctx.lineTo(8.3,38.55);ctx.lineTo(12.7,30.3);ctx.lineTo(
38.65,30.3);ctx.lineTo(43.05,38.55);ctx.lineTo(51.35,38.55);ctx.moveTo(34.9,23
.5);ctx.lineTo(16.5,23.5);ctx.lineTo(25.7,6.45);ctx.lineTo(34.9,23.5);

• コードを自動生成することで、パース等に必要な余
計なコストを削除する
– 最初から自動生成したコードを使用するのもあり

• ちなみに上記コードを実行するとこれが出る

Broadtail Confidential

Confidential
22
23

GPUを意識した高速化(1)
• GPUキャッシュに描画する画像が乗るように意識す
る
– GPUは高速化のために内部に画像キャッシュがあり、キャッ
シュ画像で再描画する際にはCPUからGPUにデータを転送せ
ずにすむ

• どうすればキャッシュに乗るのかはブラウザの情況
次第
– 必ずキャッシュに乗るように書くことは難しいが、ある程
度は可能
– 基本戦略としては安定志向と博打志向
• 安定志向:小さい画像(IMG)を複数用意し、それらを
drawImageする
• 博打志向:1024x1024等の大きい画像を用意し、そこから切り
出してdrawImageする
• 博打する場合のサイズは512x512、1024x1024等にする
Broadtail Confidential

Confidential
23

• 一定時間の間にブラウザに使われる画像を意識し、
24

GPUを意識した高速化(2)
• CanvasはGPUキャッシュに乗ることはないので、
Canvasをimgタグに変換する
– Canvasはプログラムによって変更されることが前提であるた
め、現在のブラウザの実装ではCanvasはGPUのキャッシュに
乗らない
– toDataURL APIを利用してCanvasをimgに変換することで、
GPUのキャッシュにのるようにしてやる
var src = canvas.toDataURL();
var img = document.createElement("img");
img.src = src;

– 使い終わったcanvasはきちんとGCされるように気をつける

Broadtail Confidential

Confidential
24
25

互換性問題の解決
• 先述したとおり、Android Legacy Browserは多種多様の
変更が入っており、ありとあらゆる問題が起こりう
る
ctx.clearRect(0, 0, width, height);

• こんな簡単な命令ですら、動かないときは動かない
– 問題が起こったら、ブラウザを過信せず徹底的に疑う
– なお上記の問題は以下で解決する
ctx.clearRect(0, 0, width + 1, height + 1);

Broadtail Confidential

Confidential
25
26

互換性問題の解決(2)
• ブラウザの気持ちになって考える
– ブラウザが、内部でどのような処理をしているせいでこう
なったのだろうか
– 逆にこのような結果になるためには、どのような処理を書
けば発生するだろうか
– 全体からコメントアウトしていって問題の場所を発見する
か、もしくは小さなサンプルを作って問題の最小サンプル
を作成し、問題をシンプルにして仮定を立てやすくする

Broadtail Confidential

Confidential
26
27

互換性問題の解決(3)
• 実際にあった問題
– 特定の端末で、なぜかCanvasへの描画が乱れる
• GPUプログラムにバグがあることを突き止め、GPUを利用しな
いようにCanvasのサイズを一定以上のサイズ(>2048px)にする

– 特定の端末で、なぜかCanvasのメモリが解放されないことが
ある
• 大き目のCanvasを用意して、消さずに使いまわすようにする

– 特定の端末で、なぜかimgのonloadが呼ばれないことがある
setTimeout(function() {}, 0); // 絶対に消さないこと

– 特定の端末で、なぜかJavaScriptの代入が失敗する
• 失敗しないように代入文を書き直す

– 特定の端末で、なぜか温めると表示が乱れる
• どうしろと…

Broadtail Confidential

Confidential
27
再掲: 残念なお知らせ

28

• Androidの対応は、IE6の対応より大変です

Broadtail Confidential

Confidential
28
29

メモリの問題
• メモリを使いすぎない
– メモリを使いすぎると、ブラウザは反抗する
• iPhone: 落ちる
• Android: 描画をサボる
もある

もしくは固まる

もちろん落ちること

– 自前でキャッシュ管理機構を作ってキャッシュを消去する
• LRU等の単純なアルゴリズムでも十分に効果がある

• メモリリークをしない
– ブラウザのGCにきちんと回収されるように気をつける
• 使いもしていないCanvasの参照を持ち続けていないか?
• クロージャが予想以上にスコープを確保していないか?

– 動的にメモリを確認して、メモリが微増する場所を突き止
める
• adb や インスペクタを利用する
• iOSでもAndroidでも、メモリの特性は大体同じ
• 特定の端末のみで発生する問題は、もちろんある
Broadtail Confidential

Confidential
29
30

バッテリーの問題
• 描画する部分が大きければ大きいほど、バッテリー
の消費が激しくなる
(function draw() {
setTimeout(draw, 16);
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
})();

– たとえばこのようなコードを書くと、CPUはそれほど働いて
いないにも関わらず、バッテリーはもりもり減る

• 描画をしなくていい場合には一切描画系のコマンド
を呼び出さないようにする

Broadtail Confidential

Confidential
30
31

鉄則

• 高速化もメモリ管理も、実際のデータをもとに確認
する

• どうしようもないこともある

Broadtail Confidential

Confidential
31
32

デモ

32
33

Canvasをとことん使ったデモ

ダンジョンポッパー
mobageでリリース中
iPhone/Android対応

Google I/O 2013で発表した
HTML5ゲームのデモ

Broadtail Confidential

Confidential
33
最後に

34

• ブラウザHTML5には、アプリでは絶対に達成できな
いメリットがある一方で、アプリに比べ劣っている
点も多い
• HTML5らしさを出したWebアプリはほとんど出てい
ない
– モバイルHTML5が世界で一番進んでいるのが日本

• 将来、アプリがWebに置き換わっていくのはほぼ確
実
• HTML5のメリットをフル活用し、欠点の少ないアプ
リが簡単に作れるようになれば、世界を制すること
Broadtail Confidential
が出来る
Confidential
34
35

ぜひ皆さんで一緒に、次世代のWebアプリを世界に普及
させましょう!

Broadtail Confidential

Confidential
35
36

ご清聴、ありがとうございました
紀平 拓男 @tkihira

Broadtail Confidential

Confidential
36
37

Broadtail Confidential

Confidential
37

More Related Content

HTML5 conference 2013