blob: ee8d9adb454f15f14524e1b52988577935b152f1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
---
title: パフォーマンスの基本
slug: Archive/B2G_OS/Performance
tags:
- B2G
- Firefox OS
- Guide
- Performance
translation_of: Web/Performance/Fundamentals
---
<div class="summary">
<p><span class="seoSummary">パフォーマンスは効率とも言い換えられます。このドキュメントは、パフォーマンスとは何か、ブラウザープラットフォームがその改善にどう役立つか、そのテストと改善にどのようなツールやプロセスが使えるかを、Open Web Apps の文脈で一般的な視点から解説します。</span></p>
</div>
<h2 id="What_is_performance.3F" name="What_is_performance.3F">パフォーマンスとは何か?</h2>
<p>究極的には、ユーザーによって知覚されるパフォーマンスが唯一重要なパフォーマンスです。ユーザーは、タッチ、動作、音声を通じてシステムに入力を与え、その引き替えに視覚、触覚、聴覚を通じて出力を感知します。パフォーマンスとは、ユーザーの入力に応えるシステム出力の質と言えます。</p>
<p>他の条件がすべて同じであると仮定すれば、ユーザーによって知覚されるパフォーマンス (以降 UPP と言います) を除く一部の対象に対して最適化されたコードは、UPP に対して最適化されたコードとの競争に敗れます。ユーザーは、例えば、毎秒 100,000,000 件を処理するものの動作がギクシャクとした応答性の低いアプリより、毎秒 1,000 件のデータベーストランザクション処理しか行わなくても応答性の高いスムーズなアプリを好みます。もちろん、これは決して他の指標への最適化が無意味と言うことではありませんが、現実的な UPP 対象が優先されるのです。</p>
<p>次のいくつかの小項目では、最も重要なパフォーマンス指標について取り上げ解説します。</p>
<h3 id="Responsiveness" name="Responsiveness">応答性</h3>
<p>応答性とは単に、ユーザーの入力に対してシステムがどれだけ速く出力 (複数になることもあります) を返すかということです。例えばユーザーは、スクリーンをタップしたときに、何らかの方法でピクセルに変化が起きると考えます。このインタラクションでは、応答性の指標はタップからピクセル変化までの所要時間が応答性の指標となります。</p>
<p>応答性は時に、フィードバックで複数の段階を必要とします。アプリケーションの起動は特に重要なケースのひとつであり、これについては後ほど詳しく説明します。</p>
<p>ユーザーは無視されたときに不満を募らせ腹を立てるという単純な理由から、応答性は重要です。ある入力に対して応答するまでの間、アプリは刻々とユーザーを無視していることになるのです。</p>
<h3 id="Framerate" name="Framerate">フレームレート</h3>
<p>フレームレートとは、システムがユーザーに表示するピクセルを変更する速度です。これはよく知られている概念です。例えば毎秒 60 フレームを表示するゲームは、理由を説明できなくても毎秒 10 フレームを表示するゲームよりも人々に好まれます。</p>
<p>フレームレートは「サービス品質」の指標として重要です。コンピューターのディスプレイは現実をまねた光を届けることにより、ユーザーの「おろかな」目向けに設計されています。例えば、印刷された文字で覆われた紙はいくつかのパターンでユーザーの目に光子を反射します。ピクセルを操作することで、リーダーアプリは同様のパターンで光子を発してユーザーの目を「だまして」います。</p>
<p>あなたの頭脳が推測するように、動作はギクシャク動いたり不連続であったりするのではなく、むしろスムーズかつ連続的に「更新」します。(ストロボはこれをひっくり返して、不連続な現実の錯覚を作り出すように脳への入力を減らすため、楽しいものです。) コンピューターのディスプレイ上では、単純により高いフレームレートの方が現実をより忠実に再現できます。</p>
<div class="note">
<p><strong>注</strong>: 人間は通常 60Hz より高いフレームレートの違いを知覚できません。これが、現代のほとんどのディスプレイが 60Hz でリフレッシュするよう設計されている理由です。例えばハチドリには、テレビがおそらくぎくしゃくして非現実的なものに見えるでしょう。</p>
</div>
<h3 id="Memory_usage" name="Memory_usage">メモリー使用量</h3>
<p><strong>メモリー使用量</strong>もまた重要な指標です。応答性やフレームレートとは異なり、ユーザーはメモリー使用量を直接は知覚できませんが、メモリー使用量は「ユーザー状態」と密接しています。理想的なシステムは、常に 100% のユーザー状態を維持するでしょう: システム内の全アプリケーションが同時に動作し、また全アプリケーションが、ユーザーが直前にアプリケーションと行った対話によってもたらされた状態を維持します (アプリケーションの状態はコンピューターのメモリーに保存されることが、密接している理由です。)</p>
<p>これは重要かつ直感に反した帰結を見ることとなります。よく設計されたシステムは、<strong>空き</strong>メモリーの量を最大化するようには最適化していないはずです。メモリーはリソースであり、また空きメモリーは使用していないリソースです。むしろよく設計されたシステムは、ユーザー状態を維持するために可能な限り多くのメモリーを<strong>使用する</strong>ように最適化して、同時に他の UPP の目的を達成します。</p>
<p>それはシステムがメモリーを<strong>無駄使い</strong>して良いということではありません。システムが特定のユーザー状態を維持するのに必要なメモリーより多くのメモリーを使用することは、他のユーザー状態を保持するために使用できたりソースの無駄使いです。実際は、すべてのユーザー状態を維持できるシステムはありません。ユーザー状態のために賢くメモリーを割り当てることは、後ほど詳しく説明する通り重要事項です。</p>
<h3 id="Power_usage" name="Power_usage">電気使用量</h3>
<p>最後に挙げる指標は<strong>電気使用量</strong>です。メモリー使用量と同様に、端末がどれだけ長く他のすべての UPP の目的を維持できるかということから、ユーザーは間接的にのみ電気使用量を認識します。UPP の目的を達成するため、システムは必要最小限の電力量だけを消費しなければなりません。</p>
<p>本ドキュメントでは、これらの指標でのパフォーマンスについて説明します。</p>
<h2 id="Platform_performance" name="Platform_performance">プラットフォームパフォーマンスの最適化</h2>
<p>本章では、Firefox OS と Gecko が全アプリケーションの水準より下で、パフォーマンスに対し通常どのように寄与しているかをおおまかに説明します。開発者あるいはユーザーの視点から「プラットフォームは何を行うか」という質問に答えます。</p>
<h3 id="Web_technologies" name="Web_technologies">Web 技術</h3>
<p>Web プラットフォームには多くのツールがあり、他より特定のジョブに対してより適しているものもあります。アプリケーションのロジックは JavaScript で記述します。グラフィックを表示する場合、開発者は HTML/CSS (高レベルな記述言語) か、<a href="/ja/docs/Web/HTML/Element/canvas" title="HTML の <canvas> 要素 と Canvas スクリプティング API や WebGL API を使用して、グラフィックスやアニメーションを描画することができます。"><code><canvas></code></a> 要素が提供する低レベルな命令インターフェイス (<a href="/ja/docs/Web/WebGL">WebGL</a> を含む) を使用できます。HTML/CSS と Canvas の「中間」には <a href="/ja/docs/Web/SVG">SVG</a> があり、これは両方のメリットを提供します。</p>
<p>HTML/CSS は、時にレンダリング時のピクセルレベルの制御や秒間数フレームを犠牲にしつつ、生産性を飛躍的に高めます。テキストや画像は自動的にリフローされ、UI 要素には自動的にシステムテーマが提供され、また異なる解像度や RTL 言語など、開発者が当初考慮しないかもしれない一部のユースケースについてシステムは「組み込みの」対応を提供します。</p>
<p><code>canvas</code> 要素は、描画のためのピクセルバッファを開発者に直接与えます。これによって開発者は、レンダリングのピクセルレベルでの制御やフレームレートの正確な制御が可能となりますが、一方で様々な解像度や画面の向き、RTL 言語などに対応する必要があります。開発者は Canvas への描画に、よく知られた 2 次元描画 API か、OpenGL ES 2.0 にほぼ従う「ハードウェアに近い」バインディングである WebGL を使用できます。</p>
<div class="note">
<p><strong>注</strong>: Firefox OS は、<a href="/ja/docs/Web/HTML">HTML</a>、<a href="/ja/docs/Web/CSS">CSS</a>、<a href="/ja/docs/Web/JavaScript">JavaScript</a> といった Web 技術によって作られたアプリケーションに最適化されています。わずかな基本システムサービスを除き、Firefox OS で実行されるすべてのコードは Web アプリであり、Gecko エンジン上で動作します。OS のウィンドウマネージャーでさえ、HTML/CSS/JavaScript で記述されています。コアオペレーティングシステムがアプリケーションと同じ Web 技術で構築されているため、それら Web 技術のパフォーマンスは重要です。「逃げ道」はありません。これにより、サードパーティアプリも OS 独自の最適化によるあらゆる恩恵を受けられることから、開発者に大きなメリットをもたらします。プリインストールのコードのみ使える「魔法のようなパフォーマンス源」はありません。Firefox OS のパフォーマンスに関する詳細は <a href="/ja/Apps/Developing/Performance/Firefox_OS_performance_testing">Firefox OS パフォーマンステスト</a> を参照してください。</p>
</div>
<h3 id="Gecko_rendering" name="Gecko_rendering">Gecko のレンダリング</h3>
<p>Gecko の JavaScript エンジンは、ジャストインタイム (JIT) コンパイルに対応しています。これはアプリケーションのロジックを、Java VM など他の仮想マシンに匹敵するほど高速に実行し、また「ネイティブコード」に迫る場合もあります。</p>
<p>HTML、CSS、Canvas を支えている Gecko のグラフィックスパイプラインはいくつかの方法で最適化されています。Gecko 内の HTML/CSS のレイアウトやグラフィックスのコードは、スクロールなど一般的なケースでの無効化や再描画の回数を減らします。開発者はこの支援を「無償で」受けられます。Gecko が「自動的に」、またアプリケーションが <code>canvas</code> へ「手動で」書き込むピクセルバッファは、ディスプレイフレームバッファへ書き込まれる際にコピー量が最小化されます。これはオーバーヘッドを生み出す中間のサーフェイス (多くのオペレーティングシステムにおける、アプリケーションごとの「バックバッファ」など) を避けたり、コンポジションハードウェアが直接アクセスできるグラフィックスバッファ用の特別なメモリーを使用したりすることで実現します。複雑なシーンは最大限のパフォーマンスを得るため、端末の GPU を使用して描画されます。消費電力を低減するため、シンプルなシーンは特別な専用のコンポジションハードウェアで描画し、GPU はアイドル状態または無効化します。</p>
<p>完全に静的なコンテンツは、リッチアプリケーションよりもむしろ例外的です。リッチアプリケーションは <a href="/ja/docs/Web/CSS/animation" title="CSS の animation プロパティは、様々なアニメーションのプロパティ、 animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, animation-play-state の 一括指定プロパティです。"><code>animation</code></a> や <a href="/ja/docs/Web/CSS/transition" title="CSS の transition プロパティは、 transition-property、 transition-duration、 transition-timing-function、 transition-delay の一括指定プロパティです。"><code>transition</code></a> 効果とともに動的なコンテンツを使用します。トランジションやアニメーションは、アプリケーションにとって特に重要です。開発者は CSS を使うことで、シンプルで高レベルな構文を使用して複雑な挙動を宣言できます。一方、Gecko のグラフィックスパイプラインは、一般的なアニメーションを効率的に描画するよう、高度に最適化されています。一般的なアニメーションはシステムのコンポジション機能に「押しつけられ」、ハイパフォーマンスかつ低消費電力で描画できます。</p>
<p>アプリケーションの実行パフォーマンスも重要ですが、起動時のパフォーマンスも同様に重要です。Gecko は、多種多様なコンテンツ、つまり Web 全体を効率的に読み込むよう最適化されています。HTML パースの並列処理、リフローや画像デコードの賢いスケジューリング、優れたレイアウトアルゴリズムなど、こうしたコンテンツに対して行われた長年にわたる改良が、Firefox 上で実行される Web アプリケーションのパフォーマンス改善にも適用されます。</p>
<div class="note">
<p><strong>注</strong>: 起動時のパフォーマンスをさらに改善するには、Firefox OS 固有の詳しい情報を <a href="/ja/Apps/Developing/Performance/Firefox_OS_performance_testing">Firefox OS パフォーマンステスト</a> で参照してください。</p>
</div>
<h2 id="Application_performance" name="Application_performance">アプリケーションのパフォーマンス</h2>
<p>本章は、「自分のアプリを高速にするために何ができるか」という疑問を持つ開発者に向けたものです。</p>
<h3 id="Startup_performance" name="Startup_performance">起動時のパフォーマンス</h3>
<p>アプリケーションの起動は一般的に、ユーザーが知覚する 3 つのイベントに分けられると言われます。</p>
<ul>
<li>最初に、アプリケーションの「初回描画」です。最初のフレームを描画するのに十分なアプリケーションのリソースが読み込まれた時点です。</li>
<li>次に、アプリケーションが<strong>インタラクティブ</strong>になったときです。例えば、ユーザーがボタンをタップしてアプリケーションが反応するときです。</li>
<li>最後のイベントは「読み込み完了」であり、例えば音楽プレイヤーでユーザーのアルバムすべてが表示されたときです。</li>
</ul>
<p>高速起動の秘訣は、以下 2 点を覚えておくことです。UPP こそが重要であることと、上記のユーザーが知覚するイベントそれぞれに至る「クリティカルパス」があることです。クリティカルパスはイベントが発生するまでに実行しなければならない、完全かつ最適なコードです。</p>
<p>例えばいくつかの HTML と HTML にスタイル付けする CSS で視覚的に構成される、アプリケーションの最初のフレームを描画するときは、次のような流れとなります。</p>
<ol>
<li>HTML を解析する</li>
<li>その HTML の DOM を構築する</li>
<li>DOM の一部である画像などのリソースを読み込みデコードする</li>
<li>CSS スタイルをその DOM に適用する</li>
<li>スタイル付けしたドキュメントをリフローする</li>
</ol>
<p>この中に「一般的ではないメニューに必要な JS ファイルを読み込む」「ハイスコア一覧用の画像を読み込んでデコードする」などはありません。これらの作業項目は、最初のフレームを描画するためのクリティカルパス上にないからです。</p>
<p>これは明らかですが、ユーザーが知覚する起動イベントへより早く達するための主な「トリック」は、「クリティカルパス上にあるコードのみ」実行することです。また、シーンをシンプルにしてクリティカルパスを短くしましょう。</p>
<p>Web プラットフォームは高度に動的です。JavaScript は動的型付け言語であり、また Web プラットフォームではコード、HTML、CSS、画像、その他のリソースを動的に読み込むことが可能です。これらの機能は必要ではないコンテンツを起動後に "ゆっくりと" 読み込むことにより、クリティカルパスから外れる作業を遅れて行うために使用できます。</p>
<p>起動を遅らせるもうひとつの問題はアイドル時間であり、(データベースの読み込みといった) リクエストへのレスポンスを待つことにより発生します。この問題を避けるため、アプリケーションは起動時にできるだけ早くリクエストを発行すべきです (これは「フロントローディング」と呼ばれます)。すると後でデータが必要になったとき、それはおそらくすでに読み込まれており、アプリケーションは待つ必要がないでしょう。</p>
<div class="note">
<p><strong>注</strong>: 起動時のパフォーマンス改善に関する詳しい情報は <a href="/ja/Apps/Developing/Performance/Optimizing_startup_performance">起動パフォーマンスの最適化</a> を参照してください。</p>
</div>
<p>また、ローカルにキャッシュされた静的リソースは、高レイテンシかつ低帯域のモバイルネットワークを通じて取得される動的なデータよりも格段に速く読み込まれます。アプリケーション起動初期のクリティカルパスにネットワークリクエストを含むべきではありません。ローカルにリソースをキャッシュすることは、アプリケーションをオフラインで使用可能にする唯一の方法でもあり、標準的な Open Web Apps では、現時点ではこのために HTML5 <a href="/ja/docs/HTML/Using_the_application_cache">AppCache</a> を使う必要があります。</p>
<div class="note">
<p><strong>注</strong>: Firefox OS では、圧縮 ZIP ファイルに「パッケージ」するか、HTML5 <a href="/ja/docs/HTML/Using_the_application_cache">AppCache</a> を通じて「ホスト」するか、いずれかの方法でアプリケーションとしてインストールすることで、アプリケーションによるリソースのキャッシュを可能にしています。特定のアプリケーションタイプ向けのこれら選択肢からどのように選択するかは本ドキュメントの範囲を超えますが、一般的にアプリケーションパッケージは最適な読み込みパフォーマンスを提供し、AppCache は比較的遅くなります。インストール可能なアプリは他の OS でもまもなく使えるようになる見込みです。</p>
</div>
<h3 id="Framerate_2" name="Framerate_2">フレームレート</h3>
<p>高フレームレートを得るためにまず考慮すべき重要なことは、適切なツールの選択です。ほぼ静的で、スクロールされ、たまにアニメーションしたりするぐらいのコンテンツには HTML と CSS を使いましょう。レンダリングで精密な制御が必要でありテーマ付けは必要ないゲームなど、高度に動的なコンテンツの実装には Canvas を使いましょう。</p>
<p>Canvas を使用して描画するコンテンツは、目標フレームレートに達するかどうかは開発者次第です。何を描画するかは開発者が直接制御します。</p>
<p>HTML/CSS コンテンツでは、高フレームレートを得るには適切な基本要素を使用します。Firefox は任意のコンテンツのスクロールに高度に最適化されています。これは通常、懸念することではありません。しかし CSS による放射状グラデーションの代わりに静的レンダリングを使用するなど、速さについて一般性と品質を配分することで、スクロールのフレームレートを目標に近づけられることがしばしばあります。CSS <a href="/ja/docs/Web/Guide/CSS/Media_queries">メディアクエリ</a> は、それらが必要なデバイスにのみ制限するための折衷策になります。</p>
<p>多くのアプリケーションは「ページ」や「パネル」の移動にトランジションやアニメーションを使用します。例えばユーザーが「設定」ボタンをタップすると、アプリケーションの設定画面に遷移したり、設定メニューが「ポップアップ」したりします。Firefox は以下のようなトランジションやアニメーションのシーンに対して高度に最適化されています。</p>
<ul>
<li>デバイスの画面サイズとほぼ同じか、より小さいページやパネルを使用する</li>
<li>CSS <code>transform</code>、<code>opacity</code> プロパティのトランジションやアニメーション</li>
</ul>
<p>これらのガイドラインに従うトランジションやアニメーションはシステムのコンポジション機能にオフロードされて、最大効率で実行されます。</p>
<h3 id="Memory_and_power_usage" name="Memory_and_power_usage">メモリーと電力使用量</h3>
<p>メモリーや電力の消費の改善は、起動速度向上の問題と似ています。不要な作業を行わない、あまり使われない UI リソースは後から読み込む、効率のよいデータ構造を使用する、画像のようなリソースが十分を最適化する、といったことです。</p>
<p>最近の CPU は、ほぼアイドル状態であるときに低消費電力モードに入ることができます。絶えずタイマーを発生させたり不要なアニメーションを実行し続けたりするアプリケーションは、CPU が低消費電力モードへ移行するのを妨げます。電力効率がよいアプリケーションは、そのようなことを行うべきではありません。</p>
<p>アプリケーションがバックグラウンドに移行するとき、そのドキュメント上で <code><a href="/ja/docs/Web/Reference/Events/visibilitychange" title="/ja/docs/Web/Reference/Events/visibilitychange">visibilitychange</a></code> イベントが発生します。このイベントは開発者の役に立ちます。アプリケーションは、このイベントを監視すべきです。バックグラウンドへ移行するときにできるだけ多くの読み込み済みリソースを手放すアプリケーションは、メモリー使用量が減り、Firefox OS アプリの場合には終了されにくくなります (下記注参照)。この結果、(すでに実行中であるという利点により)「起動」が速くなり UPP も向上します。</p>
<div class="note">
<p><strong>注</strong>: 先に述べたとおり、Firefox OS は可能な限り多くのアプリケーションを同時に実行し続けようとしますが、通常端末のメモリーが不足しているとき、場合によってはアプリケーションを終了しなければなりません。Firefox OS がメモリー使用量をどう管理しているか、メモリー不足が問題になったときに同アプリをどう終了するかといった情報は、<a href="/ja/Firefox_OS/Debugging/Debugging_OOMs">Firefox OS でのメモリー不足エラーのデバッグ</a> を参照してください。</p>
</div>
<h3 id="Specific_coding_tips_for_application_performance" name="Specific_coding_tips_for_application_performance">アプリケーションパフォーマンス改善のための具体的なコーディングのヒント</h3>
<p>以下の実用的なヒントは、上記で解説したアプリケーションパフォーマンスのひとつもしくはそれ以上を改善するのに役立つでしょう。</p>
<h4 id="Use_CSS_animations_and_transitions" name="Use_CSS_animations_and_transitions">CSS アニメーションとトランジションを使う</h4>
<p>一部のライブラリが提供する <code>animate()</code> 関数は、まだ様々なパフォーマンスの悪い技術 (例えば <a href="/ja/docs/Web/API/Window/setTimeout" title="この項目についての文書はまだ書かれていません。書いてみませんか?"><code>window.setTimeout()</code></a> や <code>top</code>/<code>left</code> 位置指定) を使っている可能性がありますので、代わりに <a href="/ja/docs/Web/Guide/CSS/Using_CSS_animations">CSS アニメーション</a> を使いましょう。たいていの場合、実際には <a href="/ja/docs/Web/Guide/CSS/Using_CSS_transitions">CSS トランジション</a> を使えば、やりたいことを実現できます。ブラウザーはそうした効果を最適化し、GPU を使用してプロセッサのパフォーマンスへの影響を最小限に抑えつつスムーズに処理するように設計されていますので、問題なく動作するはずです。もうひとつのメリットは、標準的な構文を使って、アプリの他の視覚要素とともにそれらの効果を CSS で定義できるという点です。</p>
<p>CSS アニメーションでは、<a href="/ja/docs/Web/CSS/@keyframes">キーフレーム</a> を使って、非常に細かく効果を調整することが可能です。アニメーションの表示中に実行されたイベントを監視し、そのプロセスの設定点で実行すべき他のタスクを処理することさえ可能です。<a href="/ja/docs/Web/CSS/:hover" title="CSS の :hover 疑似クラスは、ユーザーがポインティングデバイスで要素に反応したものの、アクティブ化する必要がないものを選択します。普通はユーザーがカーソル(マウスポインタ―)で要素の上をホバー(通過)させたときにこの状態になります。"><code>:hover</code></a>、<a href="/ja/docs/Web/CSS/:focus" title="CSS の :focus 疑似クラスは、フォーカスを持っている(フォームの入力のような)要素を表します。普通はユーザーが要素をクリックやタップをしたり、キーボードの[タブ]キーで選択したりしたときです。"><code>:focus</code></a>、<a href="/ja/docs/Web/CSS/:target" title="CSS の :target 疑似クラスは、 URL のフラグメントに一致する id を持つ固有の要素(対象要素)を表します。"><code>:target</code></a> といった疑似クラスを使用して、あるいは親要素へ動的にクラスを追加、削除することで、そうしたアニメーションを簡単に実行することができます。</p>
<p><a href="/ja/docs/JavaScript">JavaScript</a> でアニメーションを動的に生成あるいは変更したい場合は、James Long が作成した <a href="https://github.com/jlongster/css-animations.js/">CSS-animations.js</a> というシンプルなライブラリを使うこともできます。</p>
<h4 id="Use_CSS_transforms" name="Use_CSS_transforms">CSS トランスフォームを使う</h4>
<p>要素の位置や比率などを調整したいときは、絶対配置を変更し、その数値を自分自身で計算する代わりに、<a href="/ja/docs/Web/CSS/transform" title="transform CSS プロパティは、与えられた要素の回転、拡大縮小、傾斜、移動ができます。これは、CSS 視覚整形モデル の座標空間を変更することにより実現しています。"><code>transform</code></a> CSS プロパティを使いましょう。その理由は、先ほどと同じくハードウェアアクセラレーションです。ブラウザーはそうしたタスクを GPU 上で処理し、他のことを CPU に処理させることが可能です。</p>
<p>さらにトランスフォームは、他の方法ではおそらく実現できない機能を提供します。要素を 2 次元空間内で移動させるだけでなく、3 次元空間内の移動や、ゆがみ、回転といった処理を行えるのです。Paul Irish が、パフォーマンスの観点から <a href="http://paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/"><code>translate()</code> のメリットに関する綿密な分析を行っています</a>。ただ一般的には、CSS アニメーションを使っても同じメリットを得られます。実現したい効果のために適切なツールを使用し、最適化はブラウザーに任せましょう。また、要素の位置を変更するには、簡単に拡張可能な方法を使用できます。<code>top</code> や <code>left</code> の座標変更でそうした移動をエミュレートするとなると、コードを大量に追加しなければならないでしょう。もうひとつのメリットは <code>canvas</code> 内でも使えるという点です。</p>
<div class="note">
<p><strong>注:</strong> 今のところ、一部の環境では、ハードウェアアクセラレーションを活用するには <code>translateZ(0.1)</code> を使用する必要があります。先に述べた通り、これによってパフォーマンスを改善できますが、メモリー消費量を増大させるといった問題を引き起こす可能性もあります。この点でどう対処すべきかは開発者次第です。多少のテストを行い、あなたの具体的なアプリに最適な方法を見つけてください。</p>
</div>
<h4 id="Use_requestAnimationFrame()_instead_of_setInterval()" name="Use_requestAnimationFrame()_instead_of_setInterval()"><code>setInterval()</code> の代わりに <code>requestAnimationFrame()</code> を使う</h4>
<p><a href="/ja/docs/Web/API/Window/setInterval" title="WindowOrWorkerGlobalScope ミックスインの setInterval() メソッドは、一定の遅延間隔を置いて関数やコードスニペットを繰り返し呼び出します。これは、インターバルを一意に識別する interval ID を返します。よって clearInterval() を呼び出して、後でインターバルを削除できます。このメソッドは Window および Worker インターフェイスで提供します。"><code>window.setInterval()</code></a> の呼び出しは、現状では実行可能かどうか定かではない推定フレームレートでコードを実行します。また、ブラウザーが実際には描画していない、つまりビデオハードウェアが次の表示サイクルに達していないときにも結果を描画させようとします。これはプロセッサ時間の無駄遣いであり、ユーザーの端末のバッテリー寿命を縮める結果にもなります。</p>
<p>代わりに <a href="/ja/docs/Web/API/Window/requestAnimationFrame" title="このメソッドは、いつでも画面上でアニメーションの更新準備が整った時に呼び出してください。これにより、ブラウザの次の再描画が実行される前にアニメーション関数が呼び出されることを要求します。このコールバックの回数は、たいてい毎秒 60 回ですが、一般的に多くのブラウザーでは W3C の勧告に従って、ディスプレイのリフレッシュレートに合わせて行われます。ただし、コールバックの確率は、バックグラウンドのタブや隠れた <iframe> では、パフォーマンス向上やバッテリー消費を減らすために低くなるでしょう。"><code>window.requestAnimationFrame()</code></a> を使ってみましょう。これは、ブラウザーが実際にアニメーションの次のフレームのビルドを開始する準備が整うまで待機し、ハードウェアが実際には何も描画しようとしていない場合は実行されません。この API が持つもうひとつのメリットは、アプリが画面上に表示されていないとき (バックグラウンドのタブにあって他のタスクが実行されている場合など) はアニメーションが実行されないということです。これはバッテリー消費を抑え、ユーザーの間で悪評が立つのを防ぐことにもなります。</p>
<h4 id="Make_events_immediate" name="Make_events_immediate">イベントを即時に実行する</h4>
<p>保守的な、アクセシビリティに配慮した Web 開発者として、私たちはキーボード入力にも対応しているクリックイベントを気に入っています。モバイル端末上では、それらは非常に遅くなります。代わりに <code><a href="/ja/docs/Web/Reference/Events/touchstart" title="/ja/docs/Web/Reference/Events/touchstart">touchstart</a></code> や <code><a href="/ja/docs/Web/Reference/Events/touchend" title="/ja/docs/Web/Reference/Events/touchend">touchend</a></code> を使うべきです。その理由は、アプリの動作が緩慢であると感じさせるような遅延が発生しないということです。タッチ対応を始めにテストする場合、アクセシビリティも犠牲にしてはいけません。例えば、Financial Times はそのために、一般公開もされている <a href="https://github.com/ftlabs/fastclick">fastclick</a> というライブラリを使用しています。</p>
<h4 id="Keep_your_interface_simple" name="Keep_your_interface_simple">インターフェイスをシンプルに保つ</h4>
<p>HTML5 アプリに見られる大きなパフォーマンス問題のひとつに、多くの <a href="/ja/docs/DOM">DOM</a> 要素を移動させることで、特にグラデーションやドロップシャドウを多用している場合、あらゆる動作が緩慢になるということが挙げられます。デザインをシンプルにし、ドラッグ&ドロップ処理を行う場合は仮の要素を移動させることで、そうした問題を大幅に改善することが可能です。</p>
<p>例えば、アプリ内に要素の長大なリスト (ツイート一覧など) がある場合、それらをすべて移動させようとしてはいけません。その代わりに、表示されているツイートと、その前後にある多少のツイートだけを DOM ツリー内に保持することも可能でしょう。残りは隠すか削除しましょう。DOM へアクセスする代わりに JavaScript オブジェクト内にデータを保持することで、アプリのパフォーマンスを大幅に向上させることができます。表示を、データそのものではなく、データの表現として考えましょう。これは本来の HTML をソースとして使えないということではありません。ユーザーがツイートを読んで 10 要素分スクロールしたら、表示されていない 100 要素を移動する代わりに、結果リスト内の位置によって最初と最後のコンテンツを変更するのです。同じテクニックはスプライト処理を行うゲームにも当てはまります。要素が画面上にない場合は、それらにポーリングを行う必要はありません。代わりに、画面外に出た要素を画面内に入る要素として再利用すれば良いのです。</p>
<h2 id="General_application_performance_analysis" name="General_application_performance_analysis">一般的なアプリケーションパフォーマンス解析</h2>
<p>Firefox、Chrome、その他のブラウザーには、遅いページレンダリングの原因を突き止めるのに役立つ組み込みのツールが含まれています。特に、<a href="/ja/docs/Tools/Network_Monitor">Firefox のネットワークモニター</a> は、ページ上のネットワークリクエストがいつ発生したか、どのぐらいの大きさで、どのぐらい時間が掛かったかという正確なタイムラインを表示できます。</p>
<p><img alt="GET リクエスト、複数ファイル、各リソースの読み込みに掛かった個別の時間をグラフ上に表示している Firefox のネットワークモニター" src="https://mdn.mozillademos.org/files/6845/network-monitor.jpg" style="display: block; height: 713px; margin: 0px auto; width: 700px;"></p>
<p>実行に時間の掛かる JavaScript コードがページに含まれている場合、<a href="/ja/docs/Tools/Profiler">JavaScript プロファイラ</a> で最も遅いコードの行数を特定できます。</p>
<p><img alt="完了したプロファイル 1 を表示している Firefox JavaScript プロファイラ" src="https://mdn.mozillademos.org/files/6839/javascript-profiler.png" style="display: block; height: 433px; margin: 0px auto; width: 896px;"></p>
<p><a href="/ja/docs/Performance/Profiling_with_the_Built-in_Profiler">組み込み Gecko プロファイラ</a> は、プロファイラの実行中にブラウザーコードのどの部分が遅いかについてさらに詳しい情報を提供する大変便利なツールです。これは使い方が多少複雑ですが、多くの有益な詳細情報を提供してくれます。</p>
<p><img alt="多数のネットワーク情報を表示している組み込み Gecko プロファイラウィンドウ" src="https://mdn.mozillademos.org/files/6837/gecko-profiler.png" style="display: block; height: 514px; margin: 0px auto; width: 896px;"></p>
<div class="note">
<p><strong>注</strong>: これらのツールは Android ブラウザーでも使用できます。Firefox を起動し <a href="/ja/docs/Tools/Remote_Debugging">リモートデバッグ</a> を有効にしてください。</p>
</div>
<p><a href="https://addons.mozilla.org/ja/firefox/addon/yslow/">YSlow</a> (<a href="https://getfirebug.com/">Firebug</a> アドオンの拡張機能) は、パフォーマンス改善のため非常に有益なアドバイスを提供してくれます。特定された問題と提案された解決策の多くはモバイルブラウザーで特に有益なものです。絶対に YSlow を実行し、そのアドバイスに従うべきです。</p>
<p><img alt="パフォーマンス改善のためのヒントを表示している YSlow ウィンドウ。1 番目は HTTP リクエストを減らしましょうというもの。" src="https://mdn.mozillademos.org/files/6843/yslow.png" style="display: block; height: 240px; margin: 0px auto; width: 605px;"></p>
<p>特に、ネットワークリクエストを多数実行すること、モバイルブラウザーでは時間が掛かります。巨大な画像のレンダリングや CSS グラデーションも時間が掛かるでしょう。モバイルハードウェアは時として利用可能な帯域をすべて活用するには遅すぎるため、巨大なファイルのダウンロードは高速なネットワーク上でさえ時間が掛かります。モバイル Web パフォーマンスに関する有益で一般的なヒントは、Maximiliano Firtman の <a href="http://www.slideshare.net/firt/mobile-web-high-performance">モバイル Web ハイパフォーマンス</a> プレゼンテーションにあります。</p>
<h3 id="Testcases_and_submitting_bugs" name="Testcases_and_submitting_bugs">テストケースの作成とバグの報告</h3>
<p>Firefox と Chrome の開発者ツールが問題発見の役に立たない場合、あるいは Web ブラウザーが問題を引き起こしている可能性があるという情報を示している場合、問題を最大限に分離した最小限のテストケースを用意してみてください。おそらく問題の診断に役立つでしょう。</p>
<p>HTML ページの (埋め込まれている画像、スタイルシート、スクリプトを含む) 静的なコピーを保存して読み込むことで問題を再現できるか確かめてください。その場合、その静的なファイルを編集してあらゆる個人情報を削除した上で、他の人に送って助けを求めましょう (例えば <a href="https://bugzilla.mozilla.org">Bugzilla</a> にバグを報告するか、サーバー上に置いて URL を共有してください)。上記のツールを使って収集したプロファイル情報があればそれも共有すべきでしょう。</p>
|