diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/tools/performance | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/ja/tools/performance')
-rw-r--r-- | files/ja/tools/performance/allocations/index.html | 86 | ||||
-rw-r--r-- | files/ja/tools/performance/call_tree/index.html | 128 | ||||
-rw-r--r-- | files/ja/tools/performance/examples/index.html | 12 | ||||
-rw-r--r-- | files/ja/tools/performance/examples/sorting_algorithms_comparison/index.html | 73 | ||||
-rw-r--r-- | files/ja/tools/performance/flame_chart/index.html | 103 | ||||
-rw-r--r-- | files/ja/tools/performance/frame_rate/index.html | 58 | ||||
-rw-r--r-- | files/ja/tools/performance/how_to/index.html | 62 | ||||
-rw-r--r-- | files/ja/tools/performance/index.html | 80 | ||||
-rw-r--r-- | files/ja/tools/performance/profiler_walkthrough/index.html | 113 | ||||
-rw-r--r-- | files/ja/tools/performance/scenarios/animating_css_properties/index.html | 156 | ||||
-rw-r--r-- | files/ja/tools/performance/scenarios/index.html | 10 | ||||
-rw-r--r-- | files/ja/tools/performance/scenarios/intensive_javascript/index.html | 231 | ||||
-rw-r--r-- | files/ja/tools/performance/ui_tour/index.html | 125 | ||||
-rw-r--r-- | files/ja/tools/performance/waterfall/index.html | 478 |
14 files changed, 1715 insertions, 0 deletions
diff --git a/files/ja/tools/performance/allocations/index.html b/files/ja/tools/performance/allocations/index.html new file mode 100644 index 0000000000..29a7719108 --- /dev/null +++ b/files/ja/tools/performance/allocations/index.html @@ -0,0 +1,86 @@ +--- +title: メモリ割り当て +slug: Tools/Performance/Allocations +translation_of: Tools/Performance/Allocations +--- +<div>{{ToolsSidebar}}</div><div class="summary"> +<p>パフォーマンスツールのメモリ割り当てビューは、プロファイルの中でページ内のどの関数がもっとも多くのメモリ割り当てを行ったかを表示します。</p> + +<p>メモリを大量に割り当てたりメモリ割り当てを多数行ったりすると<a href="/ja/docs/Tools/Performance/Allocations#Allocations_and_garbage_collection">ガベージコレクション</a>を引き起こすため、パフォーマンスの観点で重要です。ガベージコレクションは、ページの応答性を損なう可能性があります。</p> +</div> + +<div class="geckoVersionNote"> +<p>メモリ割り当てビューは、Firefox 46 の新機能です。</p> +</div> + +<p>メモリ割り当てビューを有効にするため、プロファイルを記録する<em>前に</em>パフォーマンスツールの設定で "メモリ割り当てを記録" にチェックを入れなければなりません。そして通常どおり<a href="/ja/docs/Tools/Performance/How_to#Record_a_profile">プロファイルの記録</a>を行うと、ツールバーに "メモリ割り当て" という新たなタブが現れます:</p> + +<p>{{EmbedYouTube("Le9tTo7bqts")}}</p> + +<h2 id="Anatomy_of_the_allocations_view" name="Anatomy_of_the_allocations_view">メモリ割り当てビューを分析する</h2> + +<p>メモリ割り当てビューは、以下のようなものです:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/12393/allocations-view-1.png" style="display: block; height: 156px; margin-left: auto; margin-right: auto; width: 900px;"></p> + +<p>メモリ割り当てビューは、記録中に行われたメモリ割り当てを定期的にサンプリングします。それぞれの行は、記録中に少なくとも 1 回、メモリ割り当てのサンプルを取得した関数を表します。</p> + +<p>各行に、以下の列があります:</p> + +<ul> + <li>Self Count: 関数内で取得したメモリ割り当てサンプルの数 (合計に対するパーセント値も表示します)</li> + <li>Self Bytes: 関数内のメモリ割り当てサンプルで割り当てたメモリの総バイト数 (合計に対するパーセント値も表示します)</li> +</ul> + +<p>行は "Self Bytes" 列の値でソートします。</p> + +<p>よって、前出の例では以下のことが分かります:</p> + +<ul> + <li><code>signalLater()</code> で 8904 個のサンプルを取得しており、これは総サンプル数の 28.57% です。</li> + <li>それらのサンプルで 1102888 バイトのメモリを割り当てており、これはすべてのサンプルが割り当てたメモリの 30.01% です。</li> +</ul> + +<p>それぞれの関数名の隣に、展開用の三角印があります。これをクリックすると、関数を呼び出した場所がわかります:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/12397/allocations-view-2.png" style="display: block; height: 155px; margin-left: auto; margin-right: auto; width: 900px;"></p> + +<p>この例では <code>signalLater()</code> が 2 つの場所から呼び出されたことが分かります。<code>removeInner()</code> と <code>setSelectionInner()</code> です。この方法でコールスタックを戻ることができ、メモリ割り当ての状況をよく理解できます。</p> + +<h3 id="Self_Cost_and_Total_Cost" name="Self_Cost_and_Total_Cost">Self Cost と Total Cost</h3> + +<ul> +</ul> + +<p>このビューでは、列が "Self" と "Total" の 2 つのセットに分けられていることがわかるでしょう。"Self" は、関数自体で取得したサンプルを記録します。"Total" は関数自体と、この関数から呼び出した関数で取得したサンプルを記録します。ビューではツリーの葉に位置する関数をトップレベルに置きます (つまり、コールスタックを反転して表示します) ので、トップレベルではどちらも同じ値になります。一方、コールスタックを戻っていくと違いが出てくることがわかるでしょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/12397/allocations-view-2.png" style="display: block; height: 155px; margin-left: auto; margin-right: auto; width: 900px;"></p> + +<p>この図では、<code>signalLater()</code> で 8904 個のサンプルを取得しています。しかし <code>signalLater()</code> は、<code>removeInner()</code> と <code>setSelectionInner()</code> の 2 か所から呼び出されています。これらの関数はどちらも Self Count が 0 であり、その関数内で直接メモリ割り当ては行っていないことを意味します。一方、<code>removeInner()</code> の Total Count は 8901、<code>setSelectionInner()</code> の Total Count はわずか 3 です。これは 8904 回のメモリ割り当てが、<code>removeInner()</code> の枝で行われた 3回を除き、すべて <code>signalLater()</code> で発見されたことを語ります。</p> + +<h2 id="Allocations_and_garbage_collection" name="Allocations_and_garbage_collection">メモリ割り当てとガベージコレクション</h2> + +<p>当然ながらサイト内で割り当てたメモリは、知っておくと役に立つ情報です。しかし、サイトのメモリ割り当てのプロファイルとサイトの応答性を主に結びつけるものは、ガベージコレクション (GC) のコストです。</p> + +<p>ガベージコレクションを行う JavaScript などの言語は、<a href="/ja/docs/Tools/Memory/Dominators#Reachability">到達性</a>がなくなったオブジェクトを発見するためにランタイムが定期的にヒープを走査して、そのようなオブジェクトが占めていたメモリを解放しなければなりません。このような GC イベントを実行する間は JavaScript エンジンが一時停止しますので、プログラムが休止して応答性が完全になくなります。</p> + +<p>応答性への影響を軽減するため <a href="/ja/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> (Firefox の JavaScript エンジン) は少しずつ増加する GC を実施でき、GC の合間にプログラムを実行できます。それでも時にはノンインクリメンタルガベージコレクションが必要であり、この場合プログラムは完了するまで待たなければなりません。</p> + +<p>GC イベントは<a href="/ja/docs/Tools/Performance/Waterfall">タイムライン</a>ビューで赤色のマーカーで示され、時には数百ミリ秒続くなど応答性に危険信号がともります:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/12399/allocations-view-long-gc.png" style="display: block; height: 160px; margin-left: auto; margin-right: auto; width: 900px;"></p> + +<p>サイトのパフォーマンスプロファイルに GC イベントがある場合、何ができるのでしょうか? SpiderMonkey は、いつどのようなガベージコレクションを行うかを決めるために<a href="https://dxr.mozilla.org/mozilla-central/rev/584870f1cbc5d060a57e147ce249f736956e2b62/js/src/gc/GCRuntime.h#192">複雑なヒューリスティック技術</a>を使用しています。</p> + +<p>ただし、通常は<em>メモリ割り当ての圧力 (大量のメモリを割り当てる、または高い頻度でメモリを割り当てる) によって SpiderMonkey がガベージコレクションを行う可能性が高くなり、さらにインクりメンタルではないガベージコレクションを行う可能性も高くなります</em>。</p> + +<p>メモリ割り当ての圧力によってガベージコレクションが発生した場合は、タイムラインのマーカーの右側にあるサイドバーで "Show allocation triggers" という名前のリンクを表示します。このリンクをクリックすると開発ツールがメモリ割り当てビューに切り替わり、前回の GC が終了したときからクリックした GC が始まるときまでの時間帯を選択します。これにより、GC イベントを引き起こしたメモリ割り当てを集約して表示します:</p> + +<p>{{EmbedYouTube("tO5ovD9Jw4k")}}</p> + +<p>このような問題がみられる場合は、そのときに行っているメモリ割り当ての回数や量を削減できないか検討してください。例えば:</p> + +<ul> + <li>始めにメモリを割り当てるのではなく、実際必要なときに順次メモリを割り当てられませんか?</li> + <li>ループ内でメモリを割り当てている場合、ひとつのメモリ領域を毎回の処理で再使用できませんか?</li> +</ul> diff --git a/files/ja/tools/performance/call_tree/index.html b/files/ja/tools/performance/call_tree/index.html new file mode 100644 index 0000000000..d0472584d4 --- /dev/null +++ b/files/ja/tools/performance/call_tree/index.html @@ -0,0 +1,128 @@ +--- +title: コールツリー +slug: Tools/Performance/Call_Tree +tags: + - JavaScript + - パフォーマンス + - メモリ +translation_of: Tools/Performance/Call_Tree +--- +<div>{{ToolsSidebar}}</div> + +<div class="summary"> +<p>コールツリーは、どの JavaScript 関数がもっともブラウザで時間をかけているかを示します。この結果を分析すると、コードのボトルネック (ブラウザが不相応に多くの時間をかけている場所) を見つけることができます。</p> + +<p>これらのボトルネックは、最適化により最大の効果を得られる場所です。</p> +</div> + +<p>コールツリーは、サンプリングプロファイラです。これは JavaScript エンジンの状態を定期的にサンプリングして、その時点のコード実行のスタックを記録します。統計的に、個々の関数を実行しているときに取得したサンプル数はブラウザが実行にかけた時間に対応しますので、コード内のボトルネックを発見できます。</p> + +<div class="note"> +<p>本記事では、例としてシンプルなプログラムから出力した結果を使用します。自身のプロファイルで実験するためにプログラムを取得したい場合は、<a href="https://github.com/mdn/performance-scenarios/blob/gh-pages/js-call-tree-1/">こちら</a>をご覧ください。ここで言及するプロファイルは<a href="https://github.com/mdn/performance-scenarios/blob/gh-pages/js-call-tree-1/profile/call-tree.json">こちら</a>にあります。読み進めるために、インポートしてください。</p> + +<p>プログラムの構造を説明するページは<a href="/ja/docs/Tools/Performance/Examples/Sorting_algorithms_comparison">こちら</a>です。</p> + +<p>なお<a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a>のドキュメントページでも、同じプログラムおよび同じプロファイルを使用しています。</p> +</div> + +<p>以下のスクリーンショットはバブルソート、選択ソート、クイックソートの 3 種類のソートアルゴリズムを比較するプログラムの出力です。整数の乱数を埋めた配列をいくつか生成して、それぞれのアルゴリズムで順にソートします。</p> + +<p>記録内で長い JavaScript マーカーを示している部分を<a href="/ja/docs/Tools/Performance/UI_Tour#Zooming_in">ズームイン</a>しました:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10981/perf-call-tree.png" style="display: block; height: 574px; margin-left: auto; margin-right: auto; width: 1052px;"></p> + +<p>コールツリーは、表形式で結果を表示します。それぞれの行は 1 個以上のサンプルを取得した関数を表し、これらの行は関数内で取得したサンプル数の降順で並べられます。</p> + +<p><em>Samples は、この特定の関数を実行していたときに取得されたサンプル (この関数によって呼び出された他の関数) の数です。</em></p> + +<p><em>Total Time</em> <em>は、記録の選択された部分がカバーする合計時間に基づいて、その数値をミリ秒に変換したものです。これらの数値は、サンプル数とほぼ同じでなければなりません。</em></p> + +<p><em>Total Cost は、記録の選択された部分のサンプルの合計数に対するパーセンテージとしての数値です。</em></p> + +<p><em>Self Time</em> <em>は、その特定の機能で費やされた時間 (その子を除く) として計算されます。これは、キャプチャされたスタックから来ており、この関数は最も近い関数です。</em></p> + +<p><em>Self Cost は、録音の選択された部分のサンプルの合計数に対するパーセンテージとしてセルフタイムから計算されます。</em></p> + +<p>現在のバージョンのコールツリーでは、これらが最も重要な列です。<em>Self Cost </em>が比較的高い関数は、実行に時間がかかり、頻繁に呼び出されるため、最適化の候補となります。</p> + +<div class="note"> +<p><a href="https://developer.mozilla.org/ja/docs/Tools/Performance/Call_Tree$edit#Using_an_inverted_aka_Bottom-Up_Call_Tree">The inverted call tree</a> は、これらの <em>Self Cost </em>値に集中する良い方法です。</p> +</div> + +<p>このスクリーンショットは、私たちがすでに知っていると思われるものを示しています。バブルソートは非常に非効率的なアルゴリズムです。 バブルソートは選択ソートの約6倍、クイックソートの13倍です。</p> + +<h2 id="Walking_up_the_call_tree" name="Walking_up_the_call_tree">コールツリーを渡り歩く</h2> + +<p>各関数名の隣に、展開用の矢印があります。クリックすると、サンプルを取得した関数からルートに向けて、コールツリーを戻るパスを確認できます。例えば、<code>bubbleSort()</code> のエントリを展開します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10983/perf-call-tree-expanded-bubblesort.png" style="display: block; height: 512px; margin-left: auto; margin-right: auto; width: 1054px;"></p> + +<p>コールグラフは以下のとおりであるとわかります:</p> + +<pre>sortAll() + + -> sort() + + -> bubbleSort()</pre> + +<p>ここで <code>sort()</code> の<em>コスト</em> は 1.45% であり、これはリストの後方にある個別の <code>sort()</code> の値と同じであることに注意してください。これは、一部のサンプルが呼び出した関数内ではなく <code>sort()</code> 自身で取得されたことを表します。</p> + +<p>トップレベルへ戻るパスが複数存在することがあります。<code>swap()</code> のエントリを展開してみましょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10985/perf-call-tree-expanded-sawp.png" style="display: block; height: 636px; margin-left: auto; margin-right: auto; width: 1052px;"></p> + +<p><code>swap()</code> 内で 253 個のサンプルを取得しました。しかし <code>swap()</code> は 2 つの異なるパスで到達しています。<code>bubbleSort()</code> と <code>selectionSort()</code> が使用しています。<code>swap()</code> の 253 サンプルのうち 252 個は <code>bubbleSort()</code> の枝で、また 1 個だけ <code>selectionSort()</code> の枝で取得したこともわかります。</p> + +<p>これは、私たちが考えていた以上にバブルソートの効率が低いということです! 自身以外に 252 サンプル、または総コストのほぼ 10% を抱えています。</p> + +<p>このような探求によりコールグラフ全体を、関連付けられたサンプル数とともに明らかにできます:</p> + +<pre>sortAll() // 8 + + -> sort() // 37 + + -> bubbleSort() // 1345 + + -> swap() // 252 + + -> selectionSort() // 190 + + -> swap() // 1 + + -> quickSort() // 103 + + -> partition() // 12</pre> + +<h2 id="Platform_data" name="Platform_data">プラットフォームのデータ</h2> + +<p><em>Gecko</em>、<em>入力とイベント</em>などと記載された行がいくつかあるでしょう。これらは内部のブラウザ呼び出しを表します。</p> + +<p>これらも役に立つ情報です。あなたのサイトがブラウザを懸命に働かせている場合、あなたのコードではサンプルが記録されないかもしれませんが、問題は残されています。</p> + +<p>本記事の例では、679 個のサンプルが <em>Gecko </em> に割り当てられており、<code>bubbleSort()</code> に次いで 2 番目に大きいグループです。これを展開してみましょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10987/perf-call-tree-expanded-gecko.png" style="display: block; height: 478px; margin-left: auto; margin-right: auto; width: 1050px;"></p> + +<p>これは 614 個のサンプル、または総コストの役 20% が <code>sort()</code> の呼び出しに由来することを表します。<code>sort()</code> のコードを見ると、プラットフォームのデータの高いコストの理由は <code>console.log()</code> を繰り返し呼び出しているためであることが明白でしょう:</p> + +<pre class="brush: js">function sort(unsorted) { + console.log(bubbleSort(unsorted)); + console.log(selectionSort(unsorted)); + console.log(quickSort(unsorted)); +}</pre> + +<p>より効率がよい実装方法を検討することは、間違いなく有益でしょう。</p> + +<p>ここでわかることとして、アイドル時間は <em>Gecko</em> として分類されますので、プロファイル内で JavaScript を実行していない部分は <em>Gecko</em> のサンプルが増えます。これらはサイトのパフォーマンスとは関係がありません。</p> + +<div class="note"> +<p>デフォルトで、コールツリーはプラットフォームのデータを個別の関数に分割しません。これは大量のノイズを加えてしまうことと、Firefox 自体に取り組んでいる人々以外には役立たないと思われるためです。これらの詳細を確認したい場合は、<a href="/ja/docs/Tools/Performance/UI_Tour#Toolbar">設定</a>で "Gecko プラットフォームのデータを表示" にチェックを入れてください。</p> +</div> + +<h2 id="反転されたボトムアップコールツリーを使用する">反転されたボトムアップコールツリーを使用する</h2> + +<p>反転されたコールツリーはすべてのスタックの順序を逆転させ、一番近い関数コールを一番上に置きます。直接的な結果は、これは関数の Self Time 情報に焦点を当てたビューであるということです。 これはコード内のホットスポットを見つけるのに非常に便利なビューです。</p> + +<p>このビューを表示するには、[パフォーマンス]タブの右端にある歯車アイコンをクリックし、<strong>Invert Call Tree</strong> を選択します。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/16093/performance_menu_invert_call_tree.png" style="border-style: solid; border-width: 1px; display: block; height: 201px; margin: 0 auto; width: 492px;"></p> diff --git a/files/ja/tools/performance/examples/index.html b/files/ja/tools/performance/examples/index.html new file mode 100644 index 0000000000..06fadd2aca --- /dev/null +++ b/files/ja/tools/performance/examples/index.html @@ -0,0 +1,12 @@ +--- +title: Examples +slug: Tools/Performance/Examples +tags: + - TopicStub +translation_of: Tools/Performance/Examples +--- +<div>{{ToolsSidebar}}</div> + +<p>パフォーマンスシナリオとチュートリアルのデモページのリストです。</p> + +<p>{{ ListSubpages ("/ja/docs/Tools/Performance/Examples", 5) }}</p> diff --git a/files/ja/tools/performance/examples/sorting_algorithms_comparison/index.html b/files/ja/tools/performance/examples/sorting_algorithms_comparison/index.html new file mode 100644 index 0000000000..70e8a8f7b5 --- /dev/null +++ b/files/ja/tools/performance/examples/sorting_algorithms_comparison/index.html @@ -0,0 +1,73 @@ +--- +title: ソートアルゴリズムの比較 +slug: Tools/Performance/Examples/Sorting_algorithms_comparison +translation_of: Tools/Performance/Examples/Sorting_algorithms_comparison +--- +<div>{{ToolsSidebar}}</div> + +<p>この記事では、2つのパフォーマンスガイドで使用する簡単なサンプルプログラムについて説明します。<a href="/ja/docs/Tools/Performance/Call_Tree">コールツリー</a>のガイドと<a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a>のガイドです。</p> + +<p>このプログラムは、3つの異なるソートアルゴリズムのパフォーマンスを比較します。</p> + +<ul> + <li>バブルソート</li> + <li>選択ソート</li> + <li>クイックソート</li> +</ul> + +<p>これは以下の機能で構成されています。</p> + +<table class="standard-table"> + <tbody> + <tr> + <td><strong><code>sortAll()</code></strong></td> + <td>トップレベルの関数。 (200回)反復的に配列を生成し、<code>sort()</code>を呼び出します。</td> + </tr> + <tr> + <td><strong><code>sort()</code></strong></td> + <td><code>bubbleSort()</code>、<code>selectionSort()</code>、<code>quickSort()</code>を順に選択し、結果を記録します。</td> + </tr> + <tr> + <td><strong><code>bubbleSort()</code></strong></td> + <td>バブルソートを実装し、ソートされた配列を返します。</td> + </tr> + <tr> + <td><strong><code>selectionSort()</code></strong></td> + <td>選択ソートを実装し、ソートされた配列を返します。</td> + </tr> + <tr> + <td><strong><code>quickSort()</code></strong></td> + <td>クイックソートを実装し、ソートされた配列を返します。</td> + </tr> + <tr> + <td><code><strong>swap()</strong></code></td> + <td><code>bubbleSort()</code>と<code>selectionSort()</code>のヘルパー関数。</td> + </tr> + <tr> + <td><code><strong>partition()</strong></code></td> + <td><code>quickSort()</code>のヘルパー関数。</td> + </tr> + </tbody> +</table> + +<p>コールグラフは次のようになります。</p> + +<pre>sortAll() // (generate random array, then call sort) x 200 + + -> sort() // sort with each algorithm, log the result + + -> bubbleSort() + + -> swap() + + -> selectionSort() + + -> swap() + + -> quickSort() + + -> partition()</pre> + +<p>プログラムのソートアルゴリズムの実装は、<a href="https://github.com/nzakas/computer-science-in-javascript/">https://github.com/nzakas/computer-science-in-javascript/</a>から取得され、MITライセンスで使用されます。</p> + +<p><a href="https://mdn.github.io/performance-scenarios/js-call-tree-1/index.html">ここ</a>でサンプルプログラムを試してみて、<a href="https://github.com/mdn/performance-scenarios">ここ</a>でコードをクローンすることができます(gh-pagesブランチを確認してください)。 <a href="https://github.com/mdn/performance-scenarios/tree/gh-pages/js-call-tree-1/profile">私たちが議論した特定のプロフィールをダウンロードする</a>こともできます。あなたがフォローしたい場合は、パフォーマンスツールにインポートするだけです。 もちろん、独自のプロファイルを生成することもできますが、数字は少し異なります。</p> diff --git a/files/ja/tools/performance/flame_chart/index.html b/files/ja/tools/performance/flame_chart/index.html new file mode 100644 index 0000000000..3a2cf0c069 --- /dev/null +++ b/files/ja/tools/performance/flame_chart/index.html @@ -0,0 +1,103 @@ +--- +title: フレームチャート +slug: Tools/Performance/Flame_Chart +translation_of: Tools/Performance/Flame_Chart +--- +<div>{{ToolsSidebar}}</div><div class="summary"> +<p>フレームチャートはパフォーマンスのプロファイリングを行っている間、ミリ秒ごとにコードの JavaScript スタックの状態を表示します。</p> + +<p>これは記録中の任意の時点でどの関数を実際に実行しているか、またどれだけの期間実行したか、さらにどこから呼び出されたかを知る手段を提供します。</p> +</div> + +<p>呼び出しツリーとフレームチャートはどちらもサイトの JavaScript を分析するために使用します。またどちらも、記録している間定期的に取得する JavaScript エンジンのスタックのサンプルをデータとして使用します。</p> + +<p>しかし、呼び出しツリーは記録全体の合計に対してプログラムのどこでもっとも多くの時間がかかっているかを示すためにこれらのデータを編成するのに対して、フレームチャートは記録中のどこで特定の関数を実行していたかを示すためにこれらのデータを使用します。本質的には、記録中の任意の位置のコールスタックの状態を表示します。</p> + +<p>こちらは、プロファイルの一部分のフレームチャートを示したスクリーンショットです:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10989/perf-flame-chart-overview.png" style="display: block; height: 622px; margin-left: auto; margin-right: auto; width: 1676px;"></p> + +<p>始めに<a href="/ja/docs/Tools/Performance/UI_Tour#Recording_overview">記録の概要ペイン</a>で、フレームチャートに表示したい記録の一部分を選択していることがわかるでしょう。フレームチャートは大量のデータを表示しており、見やすい結果を得るためには通常、ズームインが必要です。</p> + +<p>フレームチャートビュー自体は、X 軸に沿って時間を表します。前出のスクリーンショットでは、1435ms から 1465ms の間を表示しています。Y 軸に沿ってその時点のコールスタックに存在する関数を、上にトップレベル、下に葉の関数の順に並べます。関数は区別しやすいように色分けします。</p> + +<p>これは記録中の任意の時点でどの関数を実際に実行しているか、またどれだけの期間実行したか、さらにどこから呼び出されたかを知る手段を提供します。</p> + +<h2 id="Zooming_and_panning" name="Zooming_and_panning">ズームとパン</h2> + +<p>フレームチャートを効果的に使用するため、ナビゲーションできることが必要でしょう。フレームチャートのナビゲーションに使用できる主要な操作が 2 つあります:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td><strong>ズーム</strong>: プロファイル全体のうち、フレームチャートに表示する選択範囲を増減します。</td> + <td> + <p>1) フレームチャート上でマウスホイールを上下に回します。</p> + + <p>2) フレームチャート上で、トラックパッドで 2 本の指を上下に動かします。</p> + </td> + </tr> + <tr> + <td><strong>パン</strong>: プロファイル全体内で、選択範囲を左右に動かします。</td> + <td> + <p>1) <a href="/ja/docs/Tools/Performance/UI_Tour#Recording_overview">記録の概要ペイン</a>で、選択範囲をクリック・アンド・ドラッグします。</p> + + <p>2) フレームチャートでクリック・アンド・ドラッグします。</p> + </td> + </tr> + </tbody> +</table> + +<p>{{EmbedYouTube("BzfkBRFucp8")}}</p> + +<h2 id="An_example" name="An_example">例</h2> + +<p>フレームチャートがプログラムの動作をどのように明らかにできるかを見るため、シンプルな例を見ていきましょう。<a href="/ja/docs/Tools/Performance/Call_Tree">呼び出しツリー</a>のページとで使用したものと同じサンプルを使用します。これは、3 種類の異なるソートアルゴリズムを比較するものです。このプログラムの構造の概要は、<a href="/ja/docs/Tools/Performance/Examples/Sorting_algorithms_comparison">別のページ</a>で説明しています。</p> + +<p>ここでは、呼び出しツリーで使用したものと同じプロファイルのファイルを使用します。呼び出しツリーのページではプロファイル内のプログラム呼び出しグラフと、関連付けられたサンプル数を以下のように明らかにしました:</p> + +<pre>sortAll() // 8 + + -> sort() // 37 + + -> bubbleSort() // 1345 + + -> swap() // 252 + + -> selectionSort() // 190 + + -> swap() // 1 + + -> quickSort() // 103 + + -> partition() // 12</pre> + +<p>始めに、ぷろぐらむがアクティブであった部分の全体を選択します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10991/perf-flame-chart-zoomed-out.png" style="display: block; height: 350px; margin-left: auto; margin-right: auto; width: 1212px;"></p> + +<p>最上段の紫色の箇所は <code>sortAll()</code> の呼び出しであり、プログラムの始めから終りまで実行されています。その下にあるオリーブグリーン色は、<code>sort()</code> を呼び出しています。さらに下にあるくしの歯のようなものは、それぞれのソートアルゴリズムを実行する呼び出しです。</p> + +<p>ズームしましょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10993/perf-flame-chart-zoom-1.png" style="display: block; height: 350px; margin-left: auto; margin-right: auto; width: 1212px;"></p> + +<p>この部分は約 140 ミリ秒間です。また、<code>sort()</code> が呼び出した関数をより詳しく示しています。<code>sort()</code> のコードは以下のようなものです:</p> + +<pre class="brush: js">function sort(unsorted) { + console.log(bubbleSort(unsorted)); + console.log(selectionSort(unsorted)); + console.log(quickSort(unsorted)); +}</pre> + +<p>"bubb..." と記載されたオリーブグリーン色のマーカーは、おそらく <code>bubbleSort()</code> です。緑色のマーカーは、おそらく別のソートアルゴリズムです。ひと目見ただけで、バブルソートのブロックが他のアルゴリズムより幅が広い (存続時間が長い) ことがわかります。</p> + +<p>また、<code>bubbleSort()</code> から呼ばれている関数 (紫色) がいくつかあることもわかります。</p> + +<p>もう一度ズームしましょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10995/perf-flame-chart-zoom-2.png" style="display: block; height: 348px; margin-left: auto; margin-right: auto; width: 1212px;"></p> + +<p>この部分は約 20 ミリ秒間です。<code>bubbleSort()</code> の下にある紫色のマーカーは、<code>swap()</code> の呼び出しであることがわかります。それらをすべて数えると 253 個あることが、呼び出しツリービューで示されています。ズームした範囲内ではすべて <code>bubbleSort()</code> の下にありますが、呼び出しツリービューによればプロファイル内で 1 個は <code>selectionSort()</code> の下にあります。</p> + +<p>また、緑色のマーカーのうち 2 個は <code>selectionSort()</code> および <code>quickSort()</code> であることがわかる一方で、ソート関数の呼び出しの合間にプラットフォーム (Gecko) のコードを呼び出していることもわかります。これは、<code>sort()</code> 内で <code>console.log()</code> を呼び出していることに由来する可能性が高いと考えられます。</p> diff --git a/files/ja/tools/performance/frame_rate/index.html b/files/ja/tools/performance/frame_rate/index.html new file mode 100644 index 0000000000..bbd66f03d0 --- /dev/null +++ b/files/ja/tools/performance/frame_rate/index.html @@ -0,0 +1,58 @@ +--- +title: フレームレート +slug: Tools/Performance/Frame_rate +translation_of: Tools/Performance/Frame_rate +--- +<div>{{ToolsSidebar}}</div><div class="summary"> +<p>フレームレートは、Web サイトの応答性を測定したものです。低い、あるいは不安定なフレームレートによりサイトの応答性が低い、あるいはジャンキーな状態になり、ユーザエクスペリエンスを損ないます。</p> + +<p><strong>60fps のフレームレートがなめらかなパフォーマンスの目標値であり、あるイベントに対して必要なすべての更新に与えられた時間は 16.7 ミリ秒です。</strong></p> + +<p>パフォーマンスツールでフレームレートのグラフは、記録していた間のフレームレートを表示します。サイトのどこに問題があると思われるかを迅速に示して、より深く分析するために他のツールを使用できるようにします。</p> +</div> + +<h2 id="Frame_rate_and_responsiveness" name="Frame_rate_and_responsiveness">フレームレートと応答性</h2> + +<p>フレームレートは、ビデオデバイスが生成できる画像 (またはフレーム) のペースです。これは映画やゲームで特に知られていますが、現在は Web サイトや Web アプリのパフォーマンス測定として広く使用されます。</p> + +<p>Web のパフォーマンスにおいて、フレームにはブラウザがスクリーンを更新および再描画するために必要な作業が含まれます。フレームレートは、アニメーションに対してもっとも明らかな効用があります。フレームレートが低すぎるとアニメーションがぎこちない動きになり、フレームレートが高ければスムーズになります。一方でユーザと対話することから、サイトの応答性の一般的な指標としてもフレームレートは有用です。</p> + +<p>例えばページ上のある要素にマウスポインタを動かすと要素の外見を変える JavaScript が実行されてリフローや再描画が発生する場合、すべての作業をフレーム内で完了させることが必要です。ブラウザがフレームを処理するのにかかる時間が長すぎると、ブラウザが一時的に応答しなくなった (ジャンキー) ように見えるでしょう。</p> + +<p>同様に、ページをスクロールすると多くの複雑なページ更新が発生して、許容できるフレームレートをブラウザが維持できない場合、スクロールが遅くなったりときどきフリーズするように見えたりするかもしれません。</p> + +<p>一般的に高く安定したフレームレートにより、ユーザとサイトの対話はより快適かつ魅力的になるでしょう。</p> + +<div class="note"> +<p>60fps のフレームレートがなめらかなパフォーマンスの目標値と考えられており、あるイベントに対して同時に必要なすべての更新に与えられた時間は 16.7 ミリ秒です。</p> + +<p>しかし、安定性は特に重要です。60fps を実現できない場合は低いフレームレートを安定的に実現して、サイトのフリーズをもたらすフレームレートの急な落ち込みを避けるとよいでしょう。</p> +</div> + +<h2 id="Frame_rate_graph" name="Frame_rate_graph">フレームレートのグラフ</h2> + +<p>フレームレートのグラフは、パフォーマンスツールの<a href="/ja/docs/Tools/Performance/UI_Tour#Recording_overview">記録の概要</a>の部分にあります。これはブラウザがフレームの処理を終えたときのタイムスタンプを取得して、記録していた期間のフレームレートを追跡するために使用します。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11025/perf-frame-rate.png" style="display: block; height: 66px; margin-left: auto; margin-right: auto; width: 900px;">X 軸はプロファイルを採取した期間の経過時間です。また最大フレームレート、平均フレームレート、最小フレームレートを注釈として表示します。</p> + +<h2 id="Using_the_frame_rate_graph" name="Using_the_frame_rate_graph">フレームレートのグラフを使用する</h2> + +<p>フレームレートのグラフの大きな価値は、<a href="/ja/docs/Tools/Web_Console">Web コンソール</a>と同様に、サイトのどこに問題があると思われるかを迅速に示して、より深く分析するために他のツールを使用できるようにすることです。例えば、以下にパフォーマンスツールのスクリーンショットを示します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11023/perf-fr-waterfall.png" style="display: block; height: 413px; margin-left: auto; margin-right: auto; width: 900px;"></p> + +<p>平均フレームレートはおおむね良好な値ですが、フレームレートが数十ミリ秒間落ち込むときが 3 か所あります。これはきっと、ページで実行しているアニメーションが目立ってぎこちない状況を引き起こすでしょう。</p> + +<p>フレームレートのグラフは、上部にある<a href="/ja/docs/Tools/Performance/UI_Tour#Waterfall_overview">ウォーターフォールの概要</a>と直接的に関連性があります。フレームレートが落ち込んでいる始めの 2 か所は橙色のバーと関連性があり、これは JavaScript の実行に時間をかけていることを示します。</p> + +<p>落ち込んでいる部分のひとつを選択すると、下部にあるメインの<a href="/ja/docs/Tools/Performance/Waterfall">ウォーターフォールビュー</a>をその部分だけに拡大表示して、問題を起こしている機能を知ることができます:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11027/perf-zoom.png" style="display: block; height: 504px; margin-left: auto; margin-right: auto; width: 900px;"></p> + +<p>click イベントで実行される JavaScript 関数が、メインスレッドを 170 ミリ秒間ブロックしています。</p> + +<p>どの関数でしょう? この時点のコールスタックを見るため、<a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a>に切り替えてください:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11021/perf-fr-flame-chart.png" style="display: block; height: 413px; margin-left: auto; margin-right: auto; width: 900px;"></p> + +<p>問題を起こしている関数は <code>doPointlessComputations()</code> であり、"main.js" で定義されています。これを修正するには、関数を分割して部品を <code><a href="/ja/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame</a></code> で実行するか、関数全体を <a href="/ja/docs/Web/API/Web_Workers_API/Using_web_workers">Worker</a> で実行します。<a href="/ja/docs/Tools/Performance/Scenarios/Intensive_JavaScript">集約的な JavaScript</a> の記事では、長く実行される同期式の JavaScript が引き起こす応答性の問題を解決するために、本記事のような手段をどのように利用できるかを説明します。</p> diff --git a/files/ja/tools/performance/how_to/index.html b/files/ja/tools/performance/how_to/index.html new file mode 100644 index 0000000000..ff4d540ffe --- /dev/null +++ b/files/ja/tools/performance/how_to/index.html @@ -0,0 +1,62 @@ +--- +title: 操作手順 +slug: Tools/Performance/How_to +translation_of: Tools/Performance/How_to +--- +<div>{{ToolsSidebar}}</div><h2 id="Open_the_Performance_tools" name="Open_the_Performance_tools">パフォーマンスツールを開く</h2> + +<p>パフォーマンスツールを開く方法は以下のとおりです:</p> + +<ul> + <li>Shift + F5 を押下する</li> + <li>Firefox メニューの Web 開発サブメニュー (メニューバーを表示している場合や OS X ではツールメニュー) で "パフォーマンス" を選択する</li> + <li>ツールバーに Web 開発ツールボタンがある場合は、ボタンを押して "パフォーマンス" を選択する:<img alt="" src="https://mdn.mozillademos.org/files/10997/devtools-button.png" style="height: 76px; width: 728px;"></li> +</ul> + +<h2 id="Record_a_profile" name="Record_a_profile">プロファイルを記録する</h2> + +<p>記録ペインでストップウォッチのアイコンを押下すると、新しい記録を開始します。もう一度押下すると、記録を終了します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10999/perf-start-stop-recording.png" style="display: block; height: 311px; margin-left: auto; margin-right: auto; width: 744px;"></p> + +<p><code><a href="/ja/docs/Web/API/Console/profile">console.profile()</a></code> や <code><a href="/ja/docs/Web/API/Console/profileEnd">console.profileEnd()</a></code> を使用して、Web コンソールから記録を開始および終了することもできます。</p> + +<h2 id="Save_a_profile" name="Save_a_profile">プロファイルを保存する</h2> + +<p>記録ペインで "保存" と記載されたリンクをクリックすると、プロファイルを保存します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11001/perf-howto-save.png" style="display: block; height: 311px; margin-left: auto; margin-right: auto; width: 733px;"></p> + +<h2 id="Load_a_profile" name="Load_a_profile">プロファイルを読み込む</h2> + +<p>"インポート..." をクリックしてファイルを選択すると、プロファイルを読み込みます:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11005/perf-import.png" style="display: block; height: 622px; margin-left: auto; margin-right: auto; width: 733px;"></p> + +<h2 id="Clear_all_loaded_profiles" name="Clear_all_loaded_profiles">すべてのプロファイルを消去する</h2> + +<p>"消去" をクリックすると、すべての読み込み済みプロファイルを消去します。</p> + +<div class="note"> +<p>これを行うと、すべての未保存プロファイルを失います。</p> +</div> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11007/perf-clear.png" style="display: block; height: 311px; margin-left: auto; margin-right: auto; width: 733px;"></p> + +<h2 id="Select_a_tool" name="Select_a_tool">ツールを選択する</h2> + +<p>ツールバーのボタンを使用して<a href="/ja/docs/Tools/Performance/Waterfall">ウォーターフォール</a>、<a href="/ja/docs/Tools/Performance/Call_Tree">呼び出しツリー</a>、<a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a>を切り替えます:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11009/perf-switch-tool.png" style="display: block; height: 311px; margin-left: auto; margin-right: auto; width: 733px;"></p> + +<h2 id="Configure_markers_displayed" name="Configure_markers_displayed">表示するマーカーを設定する</h2> + +<p>ツールバーのボタンを使用して、<a href="/ja/docs/Tools/Performance/Waterfall">ウォーターフォール</a>でどのマーカーを表示するかを設定できます:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11011/perf-marker-filter.png" style="display: block; height: 311px; margin-left: auto; margin-right: auto; width: 733px;"></p> + +<h2 id="Zoom_in" name="Zoom_in">拡大</h2> + +<p>記録の概要で一部分を選択すると、その部分を拡大表示します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11013/perf-zoom.png" style="display: block; height: 311px; margin-left: auto; margin-right: auto; width: 733px;"></p> diff --git a/files/ja/tools/performance/index.html b/files/ja/tools/performance/index.html new file mode 100644 index 0000000000..8abebb675e --- /dev/null +++ b/files/ja/tools/performance/index.html @@ -0,0 +1,80 @@ +--- +title: パフォーマンス +slug: Tools/Performance +translation_of: Tools/Performance +--- +<div>{{ToolsSidebar}}</div><p>パフォーマンスツールは、サイトの一般的な応答性、JavaScript やレイアウトのパフォーマンスを知ることができるツールです。パフォーマンスツールを使用してあなたのサイトで、ある期間の記録やプロファイルを作成できます。記録後は、プロファイル内でサイトをレンダリングするためにブラウザーが行ったことの<a href="/ja/docs/Tools/Performance/UI_Tour#Waterfall_overview">概要</a>や、プロファイル内の<a href="/ja/docs/Tools/Performance/Frame_rate">フレームレート</a>を表示します。</p> + +<p>プロファイルのさまざまな側面を詳しく調査するために、4 つのサブツールを使用できます:</p> + +<ul> + <li><a href="/ja/docs/Tools/Performance/Waterfall">タイムライン</a>はレイアウトの実行、JavaScript の実行、再描画、ガベージコレクションといった、ブラウザーが実行したさまざまな操作を明らかにします。</li> + <li><a href="/ja/docs/Tools/Performance/Call_Tree">呼び出しツリー</a>は、ブラウザーがもっとも多くの時間を費やした JavaScript 関数を明らかにします。</li> + <li><a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a>は、記録全体の JavaScript コールスタックを明らかにします。</li> + <li><a href="/ja/docs/Tools/Performance/Allocations">メモリ割り当て</a>ビューは、記録の中でコードが実行したヒープ割り当てを表示します。</li> +</ul> + +<p>{{EmbedYouTube("WBmttwfA_k8")}}</p> + +<hr> +<h2 id="Getting_started" name="Getting_started">はじめに</h2> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/ja/docs/Tools/Performance/UI_Tour">UI ツアー</a></dt> + <dd>パフォーマンスツールについてひととおり理解するために、UI のクイックツアーを用意しました。</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/ja/docs/Tools/Performance/How_to">操作手順</a></dt> + <dd>基本操作: ツールを開く、記録を作成・保存・読み込み・設定する</dd> +</dl> +</div> +</div> + +<hr> +<h2 id="Components_of_the_Performance_tool" name="Components_of_the_Performance_tool">パフォーマンスツールのコンポーネント</h2> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/ja/docs/Tools/Performance/Frame_rate">フレームレート</a></dt> + <dd>サイトの全体的な応答性を理解します。</dd> + <dt><a href="/ja/docs/Tools/Performance/Call_Tree">呼び出しツリー</a></dt> + <dd>サイトの JavaScript のボトルネックを発見します。</dd> + <dt><a href="/ja/docs/Tools/Performance/Allocations">メモリ割り当て</a></dt> + <dd>記録の中でコードが実施したメモリ割り当てを表示します。</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/ja/docs/Tools/Performance/Waterfall">タイムライン</a></dt> + <dd>サイトとの対話として、ブラウザーが実行した作業を理解します。</dd> + <dt><a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a></dt> + <dd>記録全体で、どの JavaScript 関数をいつ実行したかを明らかにします。</dd> +</dl> +</div> +</div> + +<hr> +<h2 id="Scenarios" name="Scenarios">シナリオ</h2> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/ja/docs/Tools/Performance/Scenarios/Animating_CSS_properties">CSS プロパティのアニメーション</a></dt> + <dd>ブラウザーがどのようにページを更新するか、およびさまざまな CSS プロパティのアニメーションがパフォーマンスにどのような影響を与えるかを、タイムラインを使用して理解します。</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/ja/docs/Tools/Performance/Scenarios/Intensive_JavaScript">集約的な JavaScript</a></dt> + <dd>長時間実行される JavaScript によって引き起こされるパフォーマンスの問題、およびこのような状況で Worker がどのように役立つかを明らかにするために、フレームチャートとタイムラインを使用します。</dd> +</dl> +</div> +</div> diff --git a/files/ja/tools/performance/profiler_walkthrough/index.html b/files/ja/tools/performance/profiler_walkthrough/index.html new file mode 100644 index 0000000000..35e36bc3a9 --- /dev/null +++ b/files/ja/tools/performance/profiler_walkthrough/index.html @@ -0,0 +1,113 @@ +--- +title: プロファイラのチュートリアル +slug: Tools/Performance/Profiler_walkthrough +translation_of: Tools/Performance/Call_Tree +--- +<div>{{ToolsSidebar}}</div><p>JavaScript プロファイラは JavaScript エンジンの状態を定期的にサンプリングして、その時点のコード実行のスタックを記録します。統計的に、個々の関数を実行しているときに取得したサンプル数はブラウザが実行にかけた時間に対応しますので、コード内のボトルネックを発見できます。</p> + +<h2 id="Analysing_profiles" name="Analysing_profiles">プロファイルを分析する</h2> + +<p>パフォーマンスツールがどのようにプロファイルを提供するかを理解するには、例を見ていくことがもっとも簡単です。以下のコードは 2 から 10,000 までの数値について素数であるかを確認して、その結果を表示します。少しおもしろくするため、素数の確認は <code><a href="/ja/docs/Web/API/WindowTimers.setTimeout">setTimeout</a></code> のコールバックとして実行します:</p> + +<pre class="brush: js">function isPrime(i) { + for (var c = 2; c <= Math.sqrt(i); ++c) { + if (i % c === 0) { + console.log(i + " is not prime"); + return; + } + } + console.log(i + " is prime"); +} + +function timedIsPrime(i) { + setTimeout(function() { + isPrime(i); + }, 100); +} + +function testPrimes() { + var n = 10000; + for (var i = 2; i != n; ++i) { + timedIsPrime(i); + } +} + +var testPrimesButton = document.getElementById("test-primes"); +testPrimesButton.addEventListener("click", testPrimes, false);</pre> + +<p>このコードを Web ページに貼り付けて実行すると、コンソールへ以下のように出力します:</p> + +<pre>"2 is prime" +"3 is prime" +"4 is not prime" +"5 is prime" +"6 is not prime"</pre> + +<p>このコードのプロファイルを取得すると、以下のように表示されるでしょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/9511/primality-profile.png" style="display: block; margin-left: auto; margin-right: auto; width: 650px;"></p> + +<p>最初の行は、<em>関数</em>列が常に <em>(ルート)</em> になります。ここでは 2 つのことを示しています: プロファイリングに 1,121.95 ミリ秒かかっており、またその間に 78 個のサンプルを取得しました。<em>(ルート)</em> の下に、サンプルの取得中にプログラムで経由した、さまざまなパスのツリーを表示します。<em>(ルート)</em> の直下に、スタックの底にあるトップレベルの関数が現れます。この例では、トップレベルの関数が 2 つあります:</p> + +<ul> + <li>click イベントのリスナである <code>testPrimes()</code></li> + <li><code>timedIsPrime()</code> 内の <code>setTimeout()</code> の引数で指定した、無名のコールバック関数</li> +</ul> + +<p><code>testPrimes()</code> の行を見ていきましょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/9515/primality-profile-testprimes.png" style="display: block; margin-left: auto; margin-right: auto; width: 650px;"></p> + +<p>ここでは、78 個のサンプルのうち 29 個を <code>testPrimes()</code> 内で取得したことがわかります。<em>合計コスト</em>の列は、サンプル数をパーセント値に置き換えたものです: <code>(29/78) * 100</code> =<code> 37.17</code></p> + +<p>ところが<em>時間</em>と<em>コスト</em>は、ともに 0 です。これは、そのスタックフレームのコードを実行している間に取得したサンプルがないためです。サンプルはすべて、関数内にネストしているブロックまたは <code>testPrimes()</code> が呼び出した関数の内部で取得したものです。これは次の行でわかります:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/9517/primality-profile-testprimes-2.png" style="display: block; margin-left: auto; margin-right: auto; width: 650px;"></p> + +<p>この行も <em>testPrimes</em> という名称です。これは 19 行目から始まる <code>for</code> ループが作成した、<code>testPrimes()</code> の新たなスタックフレームを指しています。前のフレームの<em>コスト</em>が 0 であったことから予想されるとおり、このフレームの<em>サンプル</em>列も 29 です。</p> + +<p>しかし、<em>コスト</em>と<em>時間</em>は 0 ではありません。これはいくつかのサンプルが、このフレームを実行しているときに取得されたことを表します。プロファイルではサンプルをいくつ取得したかを明示していませんが、次の <em>timedIsPrime</em> という名前の行で取得したサンプルが 24 個であることから、5 個取得したはずです。これは簡単に確認できます。<code>(5/78) * 100 = 6.41</code> であり、<em>コスト</em>の値と一致します。</p> + +<p>この分岐で残る 24 個のサンプル (全体の 30.76%) は <code>timedIsPrime()</code> で取得されました。つまり、<code>setTimeout()</code> (12 行目) を呼び出している部分です。</p> + +<p>コールツリーの別の分岐は、<code>setTimeout()</code> (13 行目) に渡した無名のコールバック関数から始まっています。ここではサンプルを 1 個取得しており、残り 48 個のサンプル (全体の 61.53%) はコールバックで呼び出す <code>isPrime()</code> で取得されました。</p> + +<p>総括すると、もっとも多くのサンプルを <code>isPrime()</code> で取得しており (全体の 61.53%)、その次が <code>timedIsPrime()</code> (全体の 30.76%)、残りは取るに足らない量です。統計的に言えば、おそらくこれらの関数がほとんどの時間を消費していますので、プログラムを高速化したい場合の有力な最適化候補になります。</p> + +<h3 id="Total_Time_and_Self_Time" name="Total_Time_and_Self_Time"><em>合計時間</em>と<em>時間</em></h3> + +<p><em>合計時間</em>と<em>時間</em>の列は<em>合計コスト</em>と<em>コスト</em>から算出していますが、直接反映したものではありません。規則的にサンプルを取得しようとしていますが、そのとおりに取得できない場合もあります。適切な時期にサンプルを取得できなかった場合は、その不規則性を補正しようとします。</p> + +<h3 id="Inverting_the_call_tree" name="Inverting_the_call_tree">呼び出しツリーを反転</h3> + +<p>既定では、プロファイラは一般的なコールスタックと同様に、呼び出しツリーを根から葉の順に表示します。つまりそれぞれのトップレベル関数、トップレベル関数が呼び出す関数、その関数から呼び出される関数、といった順になります:</p> + +<pre>testPrimes + + -> timedIsPrime + + + +(setTimeout callback) + + -> isPrime</pre> + +<p>これは論理的かつスタックが積み上げられる時系列に従っており、コールスタックを表現するための慣習的な方法でもあります。一方、時間がかかっている場所が呼び出しツリーの深部にあることがよくあります。前出の例でわかるとおり、全サンプルの 90% は 2 つの主要な分岐の終端で発生しています。</p> + +<p>多くのサンプルを記録したスタックフレームに注目させるため、呼び出しツリーを反転させるオプションがプロファイラにあります。このオプションを選択すると、プロファイラは以下のようになります:</p> + +<ul> + <li><em>コスト</em>が 0 より大きいスタックフレーム、つまり、サンプルを取得したとき実際に実行していたスタックフレームのリストを作成します。</li> + <li>リストは、スタックフレームで取得したサンプル数の順に並べ替えられます。</li> + <li>リスト内の各項目で、コールスタックをトップレベル関数に向かって逆向きに表示します。</li> +</ul> + +<p>例えば testPrimes の例を、既定の表示でもう一度示します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/9511/primality-profile.png" style="display: block; margin-left: auto; margin-right: auto; width: 650px;"></p> + +<p>呼び出しツリーを反転すると以下のようになります:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/9521/primality-profile-inverted.png" style="display: block; margin-left: auto; margin-right: auto; width: 650px;"></p> + +<p>反転した表示では、プログラムで時間がかかっている場所を効果的に目立たせていることがわかるでしょう。</p> diff --git a/files/ja/tools/performance/scenarios/animating_css_properties/index.html b/files/ja/tools/performance/scenarios/animating_css_properties/index.html new file mode 100644 index 0000000000..106a08aecc --- /dev/null +++ b/files/ja/tools/performance/scenarios/animating_css_properties/index.html @@ -0,0 +1,156 @@ +--- +title: CSS プロパティのアニメーション +slug: Tools/Performance/Scenarios/Animating_CSS_properties +translation_of: Tools/Performance/Scenarios/Animating_CSS_properties +--- +<div>{{ToolsSidebar}}</div><div class="summary"> +<p>CSS プロパティのアニメーションにかかるパフォーマンスのコストは、プロパティにより異なります。また、高コストな CSS プロパティのアニメーションは、ブラウザがスムーズなフレームレートを確保しようと努力するために <a href="/ja/docs/Glossary/Jank">jank</a> が発生する場合があります。</p> + +<p><a href="/ja/docs/Tools/Performance/Frame_rate">フレームレート</a>や<a href="/ja/docs/Tools/Performance/Waterfall">ウォーターフォール</a>は CSS アニメーションにおいてブラウザが何を行っているかを明らかにして、パフォーマンスの問題の診断を支援します。</p> +</div> + +<p><a href="/ja/docs/Web/Guide/CSS/Using_CSS_animations">CSS アニメーション</a>では複数の<a href="/ja/docs/Web/CSS/@keyframes">キーフレーム</a>を指定して、それぞれのキーフレームではアニメーションの特定の段階における要素の外見を定義するために CSS を使用します。ブラウザは、それぞれのキーフレームから次のキーフレームへ遷移することでアニメーションを作成します。</p> + +<p>JavaScript を使用して要素のアニメーションを行うのに比べて、CSS アニメーションは簡単に作れます。またブラウザはいつフレームを描画するかをより制御でき、また必要に応じてフレームを破棄できますので、パフォーマンスが高くなります。</p> + +<p>しかし CSS プロパティを変更するためのパフォーマンスコストは、プロパティにより異なります。高コストな CSS プロパティのアニメーションは、ブラウザがスムーズなフレームレートを確保しようと努力するために <a href="/ja/docs/Glossary/Jank">jank</a> が発生する場合があります。</p> + +<h2 id="The_CSS_rendering_waterfall" name="The_CSS_rendering_waterfall">CSS レンダリングのウォーターフォール</h2> + +<p>CSS が変更されたときにブラウザがページを更新するためのプロセスは、以下のステップで構成されるウォーターフォールで説明できます:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10821/css-rendering-waterfall.png" style="display: block; height: 203px; margin-left: auto; margin-right: auto; width: 546px;"></p> + +<ol> + <li><strong>スタイルを再計算</strong>: 要素の CSS プロパティが変更されるたびに、ブラウザは算出スタイルを再計算しなければなりません。</li> + <li><strong>レイアウト</strong>: 続いて、要素の位置や形状を計算するために算出スタイルを使用します。この操作は "レイアウト" と名付けられていますが、"リフロー" とも呼ばれます。</li> + <li><strong>描画</strong>: そして、ブラウザはスクリーンに要素を再描画しなければなりません。最後のステップはこの流れで示していません。ページは複数のレイヤーに分割され、それぞれを独立して描画した後に、"コンポジション" と呼ばれるプロセスで合成されます。</li> +</ol> + +<p>この流れが完了しなければスクリーンを更新できませんので、ひとつのフレーム内に一連の操作を収めなければなりません。毎秒 60 フレームが、アニメーションがスムーズに見えるレートとして広く受け入れられています。毎秒 60 フレームのレートのために、ブラウザが一連の操作を実行する時間として 16.7 ミリ秒が与えられます。</p> + +<h2 id="CSS_property_cost" name="CSS_property_cost">CSS プロパティのコスト</h2> + +<p>レンダリングのウォーターフォールにおいて、一部のプロパティは他のプロパティに比べて特にコストが高くなります:</p> + +<table class="fullwidth-table standard-table"> + <thead> + <tr> + <th scope="col">プロパティの種類</th> + <th scope="col">コスト</th> + <th scope="col">例</th> + </tr> + </thead> + <tbody> + <tr> + <td>要素の<em>形状</em>や<em>位置</em>に影響を与えるプロパティ。これらはスタイルの再計算、レイアウト、再描画を発生させる。</td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10827/recalculate-style.png" style="height: 26px; width: 123px;"> <img alt="" src="https://mdn.mozillademos.org/files/10825/layout.png" style="height: 26px; width: 123px;"> <img alt="" src="https://mdn.mozillademos.org/files/10823/paint.png" style="height: 26px; width: 123px;"></td> + <td> + <p><code><a href="/ja/docs/Web/CSS/left">left</a></code><br> + <code><a href="/ja/docs/Web/CSS/max-width">max-width</a></code><br> + <code><a href="/ja/docs/Web/CSS/border-width">border-width</a></code><br> + <code><a href="/ja/docs/Web/CSS/margin-left">margin-left</a></code><br> + <code><a href="/ja/docs/Web/CSS/font-size">font-size</a></code></p> + </td> + </tr> + <tr> + <td> + <p>形状や位置への影響はないが、個別のレイヤーでは描画されないプロパティ。レイアウトは発生しない。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10827/recalculate-style.png" style="height: 26px; width: 123px;"> <img alt="" src="https://mdn.mozillademos.org/files/10835/layout-faint.png" style="height: 52px; width: 123px;"> <img alt="" src="https://mdn.mozillademos.org/files/10823/paint.png" style="height: 26px; width: 123px;"></td> + <td> + <p><code><a href="/ja/docs/Web/CSS/color">color</a></code></p> + </td> + </tr> + <tr> + <td>個別のレイヤーで描画されるプロパティは、再描画が発生しない。更新はコンポジションで制御される。</td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10827/recalculate-style.png" style="height: 26px; width: 123px;"> <img alt="" src="https://mdn.mozillademos.org/files/10835/layout-faint.png" style="height: 52px; width: 123px;"> <img alt="" src="https://mdn.mozillademos.org/files/10839/paint-faint.png" style="height: 26px; width: 123px;"></td> + <td><code><a href="/ja/docs/Web/CSS/transform">transform</a></code><br> + <code><a href="/ja/docs/Web/CSS/opacity">opacity</a></code></td> + </tr> + </tbody> +</table> + +<div class="note"> +<p><a href="http://csstriggers.com/">CSS Triggers</a> の Web サイトで、各 CSS プロパティでどれだけのウォーターフォールが発生するかをまとめています。WebKit 固有の情報ですが、ほとんどはすべての最新ブラウザで同じです。</p> +</div> + +<h2 id="An_example.3A_margin_versus_transform" name="An_example.3A_margin_versus_transform">例: margin と transform</h2> + +<p>本章では、<a href="/ja/docs/Tools/Performance/Waterfall">ウォーターフォール</a>が <code><a href="/ja/docs/Web/CSS/margin">margin</a></code> を使用したアニメーションと <code><a href="/ja/docs/Web/CSS/transform">transform</a></code> を使用したアニメーションの違いを、どのように明らかにできるかを示します。</p> + +<p>このシナリオは、<code>margin</code> を使用したアニメーションは例外なく悪いアイデアであると納得させる意図はありません。サイトを描画するためにブラウザが何を行っているかをツールがどのようにして明らかにするか、およびパフォーマンスの問題の診断や解決のためにその情報をどのように適用できるかを示すものです。</p> + +<p>自身でも試してみたい場合は、デモ Web サイトが<a href="http://mdn.github.io/performance-scenarios/animation-transform-margin/index.html">こちら</a>にあります。サンプルは以下のようなものです:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11029/css-animations-demo.png" style="display: block; height: 677px; margin-left: auto; margin-right: auto; width: 1000px;">ここには 2 つのコントロールがあります。アニメーションを開始/停止するボタンと、<code>margin</code> のアニメーションまたは <code>transform</code> のアニメーションを選択するラジオボタンです。</p> + +<p>ページ上には複数の要素を置いており、それらに <code><a href="/ja/docs/Web/CSS/linear-gradient">linear-gradient</a></code> の背景と <code><a href="/ja/docs/Web/CSS/box-shadow">box-shadow</a></code> を追加しています。これは、双方のプロパティは描画のコストが比較的高いためです。</p> + +<p>動画版のウォークスルーも用意しています:</p> + +<p>{{EmbedYouTube("Tvu6_j8Qzfk")}}</p> + +<h3 id="Animating_using_margin" name="Animating_using_margin">margin を使用したアニメーション</h3> + +<p>"Use margin" を選択したままでアニメーションを開始して、パフォーマンスツールを開いて記録を始めましょう。記録時間は数秒だけでかまいません。</p> + +<p>最初の記録を開きます。どのような結果になるかはマシンやシステム負荷に大きく依存しますが、おそらく以下のようになるでしょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10853/margin-recording.png" style="display: block; height: 237px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p>ここでは 3 つの視点で示しています: (a) ウォーターフォールの概要、(b) フレームレート、(c) タイムラインの詳細 です。</p> + +<h4 id="Waterfall_overview" name="Waterfall_overview">ウォーターフォールの概要</h4> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10857/margin-timeline-overview.png" style="display: block; height: 58px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p>これは、<a href="/ja/docs/Tools/Performance/Waterfall">ウォーターフォール</a>をコンパクトに表示したビューです。</p> + +<p>緑色が圧倒的に多いことは、<a href="/ja/docs/Tools/Performance/Timeline#timeline-color-coding">描画に多くの時間を費やしている</a>ことを示しています。</p> + +<p> </p> + +<h4 id="Frame_rate" name="Frame_rate">フレームレート</h4> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10859/margin-frame-rate.png" style="display: block; height: 64px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p>これは、<a href="/ja/docs/Tools/Performance/Frame_rate">フレームレート</a>を表示します。ここでは平均フレームレートが 46.67fps であり、目標の 60fps をかなり下回っています。さらに悪いことにフレームレートが何度も 10 から 20 fps 台に低下しており、グラフがぎざぎざになっています。特にユーザとの対話が加わると、スムーズなアニメーションではなくなるでしょう。</p> + +<h4 id="Waterfall" name="Waterfall">ウォーターフォール</h4> + +<p>記録表示領域の残りの部分で、ウォーターフォールを表示します。ウォーターフォールをスクロールすると、以下のようなパターンが見られるでしょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10861/margin-timeline.png" style="display: block; height: 532px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p>これは<a href="/ja/docs/Tools/Performance/Scenarios/Animating_CSS_properties#The_CSS_rendering_waterfall">レンダリングのウォーターフォール</a>を表します。それぞれのアニメーションフレームで、すべての要素のスタイルを再計算してからレイアウト処理を 1 回実施して、再描画を行います。</p> + +<p>ここでは、描画が特にパフォーマンスへ悪影響を与えていることがわかります。前出のスクリーンショットでは描画処理をハイライトしており、この処理は 13.11 ミリ秒かかっていることが右側のボックスでわかります。すべての処理に割り当てられた時間は 16.7 ミリ秒しかありませんので、高いフレームレートを維持できないのは驚くことではありません。</p> + +<p>ここで<a href="/ja/docs/Tools/Page_Inspector/How_to/Examine_and_edit_CSS">インスペクタを使用して</a> box-shadow を削除すると、描画時間にどのような影響があるかを実験できます。しかし次は、<code><a href="/ja/docs/Web/CSS/margin">margin</a></code> の代わりに <code><a href="/ja/docs/Web/CSS/transform">transform</a></code> を使用して高コストな描画を完全になくす方法を見ていきます。</p> + +<h3 id="Animating_using_transform" name="Animating_using_transform">transform を使用したアニメーション</h3> + +<p>Web ページのラジオボタンを "Use transform" に切り替えて、新たに記録してみましょう。すると、以下のようになるでしょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10863/transform-recording.png" style="display: block; height: 234px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<h4 id="Waterfall_overview_2" name="Waterfall_overview_2">ウォーターフォールの概要</h4> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10869/transform-timeline-overview.png" style="display: block; height: 57px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p><a href="/ja/docs/Tools/Performance/Scenarios/Animating_CSS_properties#Waterfall_overview">margin を使用した場合</a>と比べて緑色がとても少なく、また桃色がとても多くなっています。桃色は<a href="/ja/docs/Tools/Performance/Waterfall#timeline-color-coding">レイアウトやスタイルの再計算</a>でしょう。</p> + +<h4 id="Frame_rate_2" name="Frame_rate_2">フレームレート</h4> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10865/transform-frame-rate.png" style="display: block; height: 62px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p><a href="/ja/docs/Tools/Performance/Scenarios/Animating_CSS_properties#Frame_rate">margin を使用した場合</a>と比べて、良好であるように見えます。平均値は 60fps に近く、また開始付近で 1 回落ち込んでいることを除けば高いフレームレートを維持しています。</p> + +<h4 id="Waterfall_2" name="Waterfall_2">ウォーターフォール</h4> + +<p>タイムラインビューで、フレームレートが向上した理由が示されています。<a href="/ja/docs/Tools/Performance/Scenarios/Animating_CSS_properties#Waterfall">margin を使用した場合</a>と比べて、レイアウトや (この例ではさらに重要な) 描画に少しも時間を費やしていません:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10867/transform-timeline.png" style="display: block; height: 384px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p>この例では <code>transform</code> を使用することでサイトのパフォーマンスが著しく向上しており、またどのようにおよびなぜ向上したかを、パフォーマンスツールで示すことができました。</p> diff --git a/files/ja/tools/performance/scenarios/index.html b/files/ja/tools/performance/scenarios/index.html new file mode 100644 index 0000000000..0b1a33b018 --- /dev/null +++ b/files/ja/tools/performance/scenarios/index.html @@ -0,0 +1,10 @@ +--- +title: シナリオ +slug: Tools/Performance/Scenarios +tags: + - TopicStub +translation_of: Tools/Performance/Scenarios +--- +<div>{{ToolsSidebar}}</div> + +<p>パフォーマンスシナリオ</p> diff --git a/files/ja/tools/performance/scenarios/intensive_javascript/index.html b/files/ja/tools/performance/scenarios/intensive_javascript/index.html new file mode 100644 index 0000000000..34cc1db672 --- /dev/null +++ b/files/ja/tools/performance/scenarios/intensive_javascript/index.html @@ -0,0 +1,231 @@ +--- +title: 集約的な JavaScript +slug: Tools/Performance/Scenarios/Intensive_JavaScript +translation_of: Tools/Performance/Scenarios/Intensive_JavaScript +--- +<div>{{ToolsSidebar}}</div><div class="summary"> +<p>デフォルトでブラウザはレイアウト、リフロー、ガベージコレクションだけでなく、ページ内のすべての JavaScript もひとつのスレッドで実行します。これは長い間実行する JavaScript がスレッドをブロックして、ページの不応答やユーザエクスペリエンスの悪化を招くおそれがあるということです。</p> + +<p><a href="/ja/docs/Tools/Performance/Frame_rate">フレームレート</a>および<a href="/ja/docs/Tools/Performance/Waterfall">ウォーターフォール</a>ツールを使用して、いつ JavaScript がパフォーマンスの問題を起こしているかを知る、および特に注意が必要な関数を選び出すことができます。</p> + +<p>本記事では長い間実行する JavaScript が応答性の問題を起こしているサンプルサイトを使用して、問題を修正するために 2 種類の方法を適用していきます。ひとつは長い間実行する JavaScript を複数の部品に分けて、それらのスケジューリングに <code><a href="/ja/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame</a></code> を使用する方法、もうひとつは <a href="/ja/docs/Web/API/Web_Workers_API/Using_web_workers">web worker</a> を使用して関数全体を別のスレッドに分ける方法です。</p> +</div> + +<p>自身でも試してみたい場合は、デモ Web サイトが<a class="external external-icon" href="http://mdn.github.io/performance-scenarios/js-worker/index.html">こちら</a>にあります。</p> + +<p>動画版のウォークスルーも用意しています:</p> + +<p>{{EmbedYouTube("Pcc6jQX6JDI")}}</p> + +<p>デモ Web サイトは以下のようなものです:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11031/js-worker-demo.png" style="display: block; height: 677px; margin-left: auto; margin-right: auto; width: 1000px;">ここには 3 つのコントロールがあります:</p> + +<ul> + <li>JavaScript の実行方法を制御するラジオボタン。ブロックが発生するひとつの操作をメインスレッドで実行する、<code>requestAnimationFrame()</code> を使用して小規模な操作の集まりをメインスレッドで実行する、Worker を使用して別のスレッドで実行する。</li> + <li>"Do pointless computations!" と記載された、JavaScript を実行するボタン。</li> + <li>CSS アニメーションを開始・終了するボタン。これはブラウザに、バックグラウンドで実行するタスクを与えます。</li> +</ul> + +<p>ラジオボタンで "Use blocking call in main thread" を選択して、記録を始めましょう:</p> + +<ul> + <li>"Start animations" ボタンを押します。</li> + <li>パフォーマンスプロファイルの記録を始めます。</li> + <li>"Do pointless computations!" ボタンを 2~3 回押します。</li> + <li>プロファイルの記録を終了します。</li> +</ul> + +<p>どのような結果になるかはマシンにより異なりますが、おそらく以下のようになるでしょう:</p> + +<p><a id="js-blocking-overview" name="js-blocking-overview"><img alt="" src="https://mdn.mozillademos.org/files/10891/perf-js-blocking-overview.png" style="display: block; height: 113px; margin-left: auto; margin-right: auto; width: 800px;"></a></p> + +<p>この画像の上半分は<a href="/ja/docs/Tools/Performance/UI_Tour#Waterfall_overview">ウォーターフォールの概要</a>です。これは<a href="/ja/docs/Tools/Performance/Waterfall">ウォーターフォール</a>をコンパクトに表示したビューであり、記録中にブラウザが行った処理は何かを示します。<a href="/ja/docs/Tools/Performance/Waterfall#Markers">桃色はほとんどの場合 CSS の再計算、一部はリフローです</a>。これは、プロファイルで終始実行している CSS アニメーションです。また連続したの橙色のブロックが 3 つありますが、これは JavaScript を実行していることを表します。それぞれ、ボタンを押したときです。</p> + +<p>下半分はタイムラインの概要と時系列が合わせられており、<a href="/ja/docs/Tools/Performance/Frame_rate">フレームレート</a>を示しています。記録中のほとんどはフレームレートが良好ですが、ボタンを押すたびに大きく落ち込んでいます。</p> + +<p>それら 3 か所のうちひとつを選択して、メインのウォーターフォールビューで詳しく見ることができます:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10895/perf-js-blocking-waterfall.png" style="display: block; height: 306px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p>ここではボタンを押したときに、ブラウザが JavaScript の関数をひとつまたは連続的に実行して、メインスレッドを 71.73 ミリ秒、言い換えるとフレーム 4 つ分の時間ブロックしています。</p> + +<p>どの関数でしょう? <a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a>ビューに切り替えると、それがわかります:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10893/perf-js-blocking-flame-chart.png" style="display: block; height: 230px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p>これは、その時点で実行している JS のコールスタックを表示します。スタックの一番上は <code>calculatePrimes()</code> という関数であり、ファイル名や行番号がわかります。以下に掲載したコードで、直近の呼び出し元を見てみましょう:</p> + +<pre class="brush: js">const iterations = 50; +const multiplier = 1000000000; + +function calculatePrimes(iterations, multiplier) { + var primes = []; + for (var i = 0; i < iterations; i++) { + var candidate = i * (multiplier * Math.random()); + var isPrime = true; + for (var c = 2; c <= Math.sqrt(candidate); ++c) { + if (candidate % c === 0) { + // not prime + isPrime = false; + break; + } + } + if (isPrime) { + primes.push(candidate); + } + } + return primes; +} + +function doPointlessComputationsWithBlocking() { + var primes = calculatePrimes(iterations, multiplier); + pointlessComputationsButton.disabled = false; + console.log(primes); +} +</pre> + +<p>ここではかなり大きな数に対して、(とても非効率な) 素数の判定を 50 回行っています。</p> + +<h2 id="Using_requestAnimationFrame" name="Using_requestAnimationFrame">requestAnimationFrame を使用する</h2> + +<p>この問題を解決するための最初の試みとして、関数をいくつかの自己充足した小さな関数に分割して、<code><a href="/ja/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code> を使用してそれらをスケジューリングします。</p> + +<p><code>requestAnimationFrame()</code> は与えられた関数を、各フレームで再描画を行う直前に実行するようブラウザに指示します。それぞれの関数が適度に小さければ、ブラウザは実行時間を、フレーム間に与えられた時間内に収めることができるでしょう。</p> + +<p><code>calculatePrimes()</code> の分割はとてもシンプルです。別の関数で、それぞれの値が素数であるかの計算を行います:</p> + +<pre class="brush: js">function doPointlessComputationsWithRequestAnimationFrame() { + + function testCandidate(index) { + // finishing condition + if (index == iterations) { + console.log(primes); + pointlessComputationsButton.disabled = false; + return; + } + // test this number + var candidate = index * (multiplier * Math.random()); + var isPrime = true; + for (var c = 2; c <= Math.sqrt(candidate); ++c) { + if (candidate % c === 0) { + // not prime + isPrime = false; + break; + } + } + if (isPrime) { + primes.push(candidate); + } + // schedule the next + var testFunction = testCandidate.bind(this, index + 1); + window.requestAnimationFrame(testFunction); + } + + var primes = []; + var testFunction = testCandidate.bind(this, 0); + window.requestAnimationFrame(testFunction); +}</pre> + +<p>こちらのバージョンを試してみましょう。"Use requestAnimationFrame" と記載されたラジオボタンを選択して、新たにプロファイルを記録します。すると、記録は以下のようになるでしょう:</p> + +<p><a id="js-raf-overview" name="js-raf-overview"><img alt="" src="https://mdn.mozillademos.org/files/10897/perf-js-raf-overview.png" style="display: block; height: 112px; margin-left: auto; margin-right: auto; width: 800px;"></a></p> + +<p>これはまさに、私たちが期待していたものです。<a href="#js-blocking-overview">一続きの橙色のブロック</a>に代わり、ボタンを押すたびにとても短い橙色のブロックがたくさん並んでいます。橙色のブロックは 1 個ずつのフレームに分かれて現れており、またそれぞれのブロックが、<code>requestAnimationFrame()</code> から呼び出された関数 1 個を表しています。なお、このプロファイルではボタンを 2 回しか押していないことに注意してください。</p> + +<p>関数の呼び出しは CSS アニメーションに由来する桃色のブロックの間に挟み込まれており、またそれぞれの関数は、全体のフレームレートを落とすことなく処理できるほど十分に小さくなっています。</p> + +<p>ここでは <code>requestAnimationFrame</code> が応答性の問題の解決策として機能しましたが、潜在的な問題点が 2 つあります:</p> + +<ul> + <li>長い間実行する関数を、個別の自己充足した関数に分割することが難しい場合があります。今回のシンプルなケースでも、より複雑なコードになりました。</li> + <li>分割したバージョンでは、実行時間が長くなります。実は、処理にどれだけかかるかをかなり正確に言うことができます。処理は 50 回繰り返しており、またブラウザは 1 秒間に約 60 個のフレームを生成します。よって、すべての計算を実行するためにはほぼ 1 秒かかり、これはユーザエクスペリエンスやプロファイルから明らかになります。</li> +</ul> + +<h2 id="Using_web_workers" name="Using_web_workers">Web Worker を使用する</h2> + +<p>ここでは、Web Worker を使用して問題を解決します。Web Worker を使用すると、別のスレッドで JavaScript を実行できます。メインスレッドと Worker スレッドは互いに直接呼び出すことはできませんが、非同期メッセージ API を使用して通信できます。</p> + +<p>メインスレッドのコードは以下のようになります:</p> + +<pre class="brush: js">const iterations = 50; +const multiplier = 1000000000; + +var worker = new Worker("js/calculate.js"); + +function doPointlessComputationsInWorker() { + + function handleWorkerCompletion(message) { + if (message.data.command == "done") { + pointlessComputationsButton.disabled = false; + console.log(message.data.primes); + worker.removeEventListener("message", handleWorkerCompletion); + } + } + + worker.addEventListener("message", handleWorkerCompletion, false); + + worker.postMessage({ + "multiplier": multiplier, + "iterations": iterations + }); +}</pre> + +<p>元のコードと比べたときの主な違いは、以下のものが必要であることです:</p> + +<ul> + <li>Worker を作成する</li> + <li>計算の準備ができたときに、Worker へメッセージを送信する</li> + <li>"done" メッセージをリッスンする。これは、Worker が完了したことを示すメッセージです。</li> +</ul> + +<p>また、新たに "calculate.js" ファイルが必要であり、こちらは以下のようになります:</p> + +<pre class="brush: js">self.addEventListener("message", go); + +function go(message) { + var iterations = message.data.iterations; + var multiplier = message.data.multiplier; + primes = calculatePrimes(iterations, multiplier); + + self.postMessage({ + "command":"done", + "primes": primes + }); +} + +function calculatePrimes(iterations, multiplier) { + var primes = []; + for (var i = 0; i < iterations; i++) { + var candidate = i * (multiplier * Math.random()); + var isPrime = true; + for (var c = 2; c <= Math.sqrt(candidate); ++c) { + if (candidate % c === 0) { + // not prime + isPrime = false; + break; + } + } + if (isPrime) { + primes.push(candidate); + } + } + return primes; +}</pre> + +<p>Worker では処理の開始を指示するメッセージをリッスンする、および処理が完了したときに "done" メッセージを送ることが必要です。実際に計算を行っている部分のコードは、最初のバージョンのコードと完全に同じです。</p> + +<p>このバージョンはどのように実行されるのでしょう? ラジオボタンを "Use a worker" に切り替えて、新たにプロファイルを記録してください。結果は以下のようになるでしょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10899/perf-js-worker-overview.png" style="display: block; height: 112px; margin-left: auto; margin-right: auto; width: 800px;"></p> + +<p>このプロファイルでは、ボタンを 3 回押しています。ウォーターフォールの概要で<a href="#js-blocking-overview">元のバージョンと比べると</a>、ボタンを押したときにはとても短い橙色のマーカーが 2 個あることがわかります:</p> + +<ul> + <li>click イベントの処理と Worker の処理開始を行う、<code>doPointlessComputationsInWorker()</code> 関数</li> + <li>Worker が "done" を発信したときに実行される、<code>handleWorkerCompletion()</code> 関数</li> +</ul> + +<p>これら 2 つの関数の間で Worker は素数の判定を行っていますが、メインスレッドの応答性には少しも影響を与えていないように見受けられます。これはあり得ないと思うかもしれませんが、Worker は別のスレッドで実行しますのでマルチコアプロセッサの利点を享受できます。これはシングルスレッドの Web サイトでは得られません。</p> + +<p>Web Worker の主な制限は、Worker で実行するコードでは DOM API を使用できないことです。</p> diff --git a/files/ja/tools/performance/ui_tour/index.html b/files/ja/tools/performance/ui_tour/index.html new file mode 100644 index 0000000000..ed58a0c021 --- /dev/null +++ b/files/ja/tools/performance/ui_tour/index.html @@ -0,0 +1,125 @@ +--- +title: UI ツアー +slug: Tools/Performance/UI_Tour +translation_of: Tools/Performance/UI_Tour +--- +<div>{{ToolsSidebar}}</div><p>パフォーマンスツールの UI は、大きく 4 つに分けられます:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13220/perf-tool-pieces.png" style="display: block; height: 351px; margin-left: auto; margin-right: auto; width: 808px;"></p> + +<ul> + <li><a href="/ja/docs/Tools/Performance/UI_Tour#Toolbar">ツールバー</a></li> + <li><a href="/ja/docs/Tools/Performance/UI_Tour#Recordings_pane">記録ペイン</a></li> + <li><a href="/ja/docs/Tools/Performance/UI_Tour#Recording_overview">記録の概要</a></li> + <li><a href="/ja/docs/Tools/Performance/UI_Tour#Details_pane">詳細ペイン</a>、これは以下のいずれかが入ります: + <ul> + <li><a href="/ja/docs/Tools/Performance/Waterfall">タイムライン</a></li> + <li><a href="/ja/docs/Tools/Performance/Call_Tree">呼び出しツリー</a></li> + <li><a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a></li> + </ul> + </li> +</ul> + +<h2 id="Toolbar" name="Toolbar">ツールバー</h2> + +<p>ツールバーには、以下のボタンがあります:</p> + +<ul> + <li>記録を開始および終了する</li> + <li>過去に保存した記録をインポートする</li> + <li>記録ペインを消去する。<em>これを行うと、未保存の記録をすべて失うので注意してください。</em></li> + <li>タイムラインビューで表示する<a href="/ja/docs/Tools/Performance/Waterfall#Markers">マーカー</a>をフィルタリングする</li> + <li><a href="/ja/docs/Tools/Performance/UI_Tour#Details_pane">詳細ペイン</a>のツールを切り替える</li> + <li>設定用のポップアップメニューを開く</li> +</ul> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13222/perf-toolbar.png" style="display: block; height: 434px; margin-left: auto; margin-right: auto; width: 836px;"></p> + +<h2 id="Recordings_pane" name="Recordings_pane">記録ペイン</h2> + +<p>記録ペインでは、現在のセッションで取得した記録やインポートした記録を含む、読み込み済みの全記録を一覧表示します。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10917/perf-recordings-pane.png" style="display: block; height: 337px; margin-left: auto; margin-right: auto; width: 300px;"></p> + +<p>いつでも記録を選択すると、その記録の情報を他のペインに表示します。記録ペインで別の項目をクリックすると、その記録を選択できます。"保存" をクリックすると、記録を JSON ファイルとして保存できます。</p> + +<h2 id="Recording_overview" name="Recording_overview">記録の概要</h2> + +<p>ここでは、X 軸を時間として記録全体の概要を表示します。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10919/perf-overview.png" style="display: block; height: 164px; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<p>ここにはタイムラインの概要とフレームレートのグラフという、2 つの要素があります。</p> + +<h3 id="Waterfall_overview" name="Waterfall_overview">タイムラインの概要</h3> + +<p>ここでは、<a href="/ja/docs/Tools/Performance/Waterfall">タイムライン</a>をコンパクトに表示したビューを提供します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10923/perf-waterfall-overview.png" style="display: block; height: 76px; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<p>記録した処理は、<a href="/ja/docs/Tools/Performance/Waterfall#Markers">タイムラインビューと同じ方式</a>で色分けされます。</p> + +<h3 id="Frame_rate_graph" name="Frame_rate_graph">フレームレートのグラフ</h3> + +<p>フレームレートは、記録している間のブラウザの応答性を概観します:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10921/perf-frame-rate.png" style="display: block; height: 88px; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<p><a href="/ja/docs/Tools/Performance/Frame_rate">フレームレート</a>の個別記事をご覧ください。</p> + +<h3 id="Correlating_events" name="Correlating_events">イベントを関連づける</h3> + +<p>複数の要素が同期しているため、ある要素のイベントと別の要素のイベントに関連性を見いだせる場合があります。</p> + +<p>例えば以下のスクリーンショットでは、長時間の描画操作 (タイムラインの概要では<a href="/ja/docs/Tools/Performance/Waterfall#Markers">緑色のバーで表示</a>) とフレームレートの落ち込みに関連性があります:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10925/perf-overview-correlation.png" style="display: block; height: 494px; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<h3 id="Zooming_in" name="Zooming_in">拡大</h3> + +<p>記録を詳しく調査するため、概要ビューで記録の一部分を選択できます。一部分を選択すると、その部分だけを含むようにメインビューを更新します。以下のスクリーンショットではフレームレートが落ち込んだ部分を選択して、長時間の描画操作を詳しく見ています:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10927/perf-zoomed.png" style="display: block; height: 416px; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<h2 id="Details_pane" name="Details_pane">詳細ペイン</h2> + +<p>詳細ペインでは、選択したツールの情報を表示します。ツールを切り替えるには、<a href="/ja/docs/Tools/Performance/UI_Tour#Toolbar">ツールバー</a>のボタンを使用してください。</p> + +<h3 id="Waterfall" name="Waterfall">タイムライン</h3> + +<p>タイムラインでは、記録中にブラウザが実行した操作 (JavaScript を実行、CSS を更新、ページのレイアウトを更新、再描画を実行など) を表示します。X 軸は時間を表し、記録した操作を滝のように、またブラウザが実行した操作の連続性を反映するように配置します。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10929/perf-waterfall.png" style="display: block; height: 568px; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<p>タイムラインについて詳しくは、<a href="/ja/docs/Tools/Performance/Waterfall">タイムライン</a>のページをご覧ください。</p> + +<h3 id="Call_Tree" name="Call_Tree">呼び出しツリー</h3> + +<p>呼び出しツリーは、ページで実行している JavaScript のサンプリングプロファイラです。これは JavaScript エンジンの状態を定期的にサンプリングして、その時点のコード実行のスタックを記録します。統計的に、個々の関数を実行しているときに取得したサンプル数はブラウザが実行にかけた時間に対応しますので、コード内のボトルネックを発見できます。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10949/perf-call-tree.png" style="display: block; height: 384px; margin-left: auto; margin-right: auto; width: 972px;"><br> + 呼び出しツリーについて詳しくは、<a href="/ja/docs/Tools/Performance/Call_Tree">コールツリー</a>のページをご覧ください。</p> + +<h3 id="Flame_Chart" name="Flame_Chart">フレームチャート</h3> + +<p>呼び出しツリーが記録中にサイトのどの関数で、もっとも多くの実行時間がかかったかを示すものであるなら、フレームチャートは実行中のある時点のコールスタックを示すものです:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10933/perf-flame-chart.png" style="display: block; height: 504px; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<p>フレームチャートについて詳しくは、<a href="/ja/docs/Tools/Performance/Flame_Chart">フレームチャート</a>のページをご覧ください。</p> + +<h3 id="Allocations" name="Allocations">メモリ割り当て</h3> + +<div class="geckoVersionNote"> +<p>メモリ割り当てビューは、Firefox 46 の新機能です。</p> +</div> + +<p>メモリ割り当てビューは呼び出しツリービューと似ていますが、こちらはメモリ割り当てに特化したビューです。プロファイルの中でページ内のどの関数がもっとも多くのメモリ割り当てを行ったかを表示します。</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/12413/allocations-view-1.png" style="display: block; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<p>メモリ割り当てビューは、プロファイルを記録する前にパフォーマンスツールの設定で "メモリ割り当てを記録" にチェックを入れた場合に限り表示します:</p> + +<p>{{EmbedYouTube("Le9tTo7bqts")}}</p> + +<p>メモリ割り当てビューについて詳しくは、<a href="/ja/docs/Tools/Performance/Allocations">メモリ割り当てビュー</a>のページをご覧ください。</p> diff --git a/files/ja/tools/performance/waterfall/index.html b/files/ja/tools/performance/waterfall/index.html new file mode 100644 index 0000000000..738de4cd72 --- /dev/null +++ b/files/ja/tools/performance/waterfall/index.html @@ -0,0 +1,478 @@ +--- +title: タイムライン +slug: Tools/Performance/Waterfall +translation_of: Tools/Performance/Waterfall +--- +<div>{{ToolsSidebar}}</div><div class="summary"> +<p>タイムラインは、サイトやアプリの実行でブラウザが行ったさまざまなことについて知見を得るものです。これは、サイトを実行するときにブラウザが行ったことはさまざまな種類 (JavaScript を実行、レイアウトを更新など) に分類でき、またある時点でブラウザはそれらのいずれかを行っているという考え方に基づいています。</p> + +<p>よって、例えばフレームレートが落ち込むなどパフォーマンスの問題の兆候があるときはタイムラインを開いて、記録中のある時点でブラウザが何を行っていたかを知ることができます。</p> +</div> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10951/perf-waterfall.png" style="display: block; height: 568px; margin-left: auto; margin-right: auto; width: 972px;"></p> + +<p>X 軸に沿って時間を表します。記録した操作はマーカーと呼び、ブラウザが実行した操作の連続性を反映する滝のような配置で、水平方向のバーとして表示します。</p> + +<p>マーカーを選択すると、詳細情報を右側のサイドバーで表示します。そこではマーカーの長さや、<a href="/ja/docs/Tools/Performance/Waterfall#Markers">マーカーの種類</a>に特有の詳細情報を表示します。</p> + +<h2 id="Markers" name="Markers"><a id="timeline-color-coding" name="timeline-color-coding"></a>マーカー</h2> + +<p>操作を示すマーカーは、色分けおよび名前付けされています。以下の操作を記録します:</p> + +<table class="fullwidth-table standard-table"> + <thead> + <tr> + <th scope="col" style="width: 20%;">名称および説明</th> + <th scope="col">色</th> + <th scope="col">詳細情報</th> + </tr> + </thead> + <tbody> + <tr> + <td style="width: 40%;"> + <p><a id="DOM_Event_Marker" name="DOM_Event_Marker"><strong>DOM イベント</strong></a></p> + + <p>DOM イベントへの応答として実行する JavaScript コード。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10703/orange.png" style="height: 21px; width: 60px;"></td> + <td style="width: 45%;"> + <dl> + <dt>イベント種別</dt> + <dd>例えば "click" や "message" など。</dd> + </dl> + + <dl> + <dt>フェーズ</dt> + <dd>例えば "ターゲット" や "キャプチャ" など。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p>ページ内で実行される JavaScript 関数は、関数が呼び出された理由に応じて名前付けします:</p> + + <p><strong>Script Tag<br> + setInterval<br> + setTimeout<br> + requestAnimationFrame<br> + Promise Callback<br> + Promise Init<br> + Worker<br> + JavaScript URI<br> + Event Handler</strong></p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10703/orange.png" style="height: 21px; width: 60px;"></td> + <td> + <dl> + <dt>スタック</dt> + <dd>関数につながるコールスタック。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>HTML パース</strong></p> + + <p>ページの HTML をパースするために費やした時間。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10703/orange.png" style="height: 21px; width: 60px;"></td> + <td> + <dl> + <dt>スタック</dt> + <dd>関数につながるコールスタック。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>XML パース</strong></p> + + <p>ページの XML をパースするために費やした時間。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10703/orange.png" style="height: 21px; width: 60px;"></td> + <td> + <dl> + <dt>スタック</dt> + <dd>関数につながるコールスタック。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>CSS 再計算</strong></p> + + <p>ページの要素に適用する算出スタイルを算出する。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10707/purple.png" style="height: 21px; width: 60px;"></td> + <td> + <dl> + <dt>CSS 再計算のヒント</dt> + <dd>どのようなスタイル再適用が必要かを示す文字列。以下のいずれかを手がかりとして提示します:<br> + Self<br> + Subtree<br> + LaterSiblings<br> + CSSTransitions<br> + CSSAnimations<br> + SVGAttrAnimations<br> + StyleAttribute<br> + StyleAttribute_Animations<br> + Force<br> + ForceDescendants</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>レイアウト</strong></p> + + <p>ページの要素の位置やサイズを計算する。この操作は、"リフロー" と呼ばれることがあります。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10707/purple.png" style="height: 21px; width: 60px;"></td> + <td> </td> + </tr> + <tr> + <td> + <p><strong>描画</strong></p> + + <p>スクリーンにピクセルを描画する。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10705/green.png" style="height: 21px; width: 60px;"></td> + <td> </td> + </tr> + <tr> + <td> + <p><strong>ガベージコレクション</strong></p> + + <p><a href="/ja/docs/Tools/Performance/Waterfall#Garbage_collection">ガベージコレクションイベント</a>。ノンインクリメンタル GC イベントには "(非インクリメンタル)" を付加する。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10709/red.png" style="height: 21px; width: 60px;"></td> + <td> + <dl> + <dt>発生源</dt> + <dd>GC を実行した理由を示す文字列。</dd> + <dt>非インクリメンタル GC の発生源</dt> + <dd>GC がインクリメンタルではない場合に、ノンインクリメンタル GC を実行した理由を示す文字列を表示。</dd> + </dl> + + <div class="geckoVersionNote"> + <p>Firefox 46 の新機能: GC イベントがメモリ割り当ての圧力によって発生した場合は、"Show Allocation Triggers" というリンクを表示します。このリンクをクリックすると、GC イベントの原因になったメモリ割り当てのプロファイルを表示します。</p> + + <p>詳しくは<a href="/ja/docs/Tools/Performance/Allocations#Allocations_and_garbage_collection">メモリ割り当てとガベージコレクション</a>をご覧ください。</p> + </div> + </td> + </tr> + <tr> + <td> + <p><strong>サイクルコレクション</strong></p> + + <p>C++ の参照カウントを持つデータ構造を回収します。</p> + + <p>ガベージコレクションに似ていますが、こちらは C++ のオブジェクト向けです。<a href="http://blog.kylehuey.com/post/27564411715/cycle-collection">Kyle Huey のサイクルコレクションに関するブログ記事</a>をご覧ください。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10709/red.png" style="height: 21px; width: 60px;"></td> + <td> + <dl> + <dt>種別</dt> + <dd>常に "Collect" になります。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>CC グラフ削減</strong></p> + + <p>サイクルコレクションの準備や事前の最適化です。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10709/red.png" style="height: 21px; width: 60px;"></td> + <td> + <dl> + <dt>種別</dt> + <dd>常に "ForgetSkippable" になります。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>コンソール</strong></p> + + <p><code>console.time()</code> および <code>console.timeEnd()</code> を呼び出した間の時間に合致する。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10955/gray.png" style="height: 54px; width: 60px;"></td> + <td> + <dl> + <dt>タイマー名</dt> + <dd><code>console</code> に渡した引数。</dd> + <dt>スタック開始</dt> + <dd>関数につながるコールスタック <code>console.time()</code>。</dd> + <dt>スタック終了</dt> + <dd>(Firefox 41 の新機能) <code>console.timeEnd()</code> 時点のコールスタック。<code><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code> 由来のコールバック内にある場合は、<a href="/ja/docs/Tools/Performance/Waterfall#Async_stack">"Async stack"</a> とも表示します。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>タイムスタンプ</strong></p> + + <p><code><a href="/ja/docs/Web/API/Console/timeStamp">console.timeStamp()</a></code> を 1 回呼び出す。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/10953/blue.png" style="height: 54px; width: 60px;"></td> + <td> + <dl> + <dt>Label</dt> + <dd><code>timeStamp()</code> に渡した引数。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>DOMContentLoaded</strong></p> + + <p>ドキュメントの <code><a href="/ja/docs/Web/Events/DOMContentLoaded">DOMContentLoaded</a></code> イベント。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/12191/red.png" style="height: 21px; width: 60px;"></td> + <td> </td> + </tr> + <tr> + <td> + <p><strong>Load</strong></p> + + <p>ドキュメントの <code><a href="/ja/docs/Web/Events/load">load</a></code> イベント。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/12193/blue.png" style="height: 21px; width: 60px;"></td> + <td> </td> + </tr> + <tr> + <td> + <p><strong>メインスレッドの Worker イベント</strong></p> + + <p>メインスレッドが Worker にメッセージを送信したとき、または Worker からメッセージを受け取ったときに表示します。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/12195/orange2.png" style="height: 21px; width: 60px;"></td> + <td> + <p>以下のいずれか:</p> + + <dl> + <dt>メインスレッドでデータをシリアライズ</dt> + <dd>メインスレッドは、Worker に送信するメッセージをシリアライズします。</dd> + <dt>メインスレッドでデータをデシリアライズ</dt> + <dd>メインスレッドは、Worker から受け取ったメッセージをデシリアライズします。</dd> + </dl> + </td> + </tr> + <tr> + <td> + <p><strong>Worker スレッドの Worker イベント</strong></p> + + <p>Worker がメインスレッドからメッセージを受け取ったとき、またはメインスレッドにメッセージを送信したときに表示します。</p> + </td> + <td><img alt="" src="https://mdn.mozillademos.org/files/12197/orange2-hollow.png" style="height: 21px; width: 60px;"></td> + <td> + <p>以下のいずれか:</p> + + <dl> + <dt>Worker でデータをシリアライズ</dt> + <dd>Worker は、メインスレッドに送信するメッセージをシリアライズします。</dd> + <dt>Worker でデータをデシリアライズ</dt> + <dd>Worker は、メインスレッドから受け取ったメッセージをデシリアライズします。</dd> + </dl> + </td> + </tr> + </tbody> +</table> + +<p>マーカーとその色はタイムラインツールと<a href="/ja/docs/Tools/Performance/UI_Tour#Waterfall_overview">タイムラインの概要</a>で同じであり、双方を関連づけることが容易になります。</p> + +<h3 id="Filtering_markers" name="Filtering_markers">マーカーのフィルタリング</h3> + +<p><a href="/ja/docs/Tools/Performance/UI_Tour#Toolbar">ツールバー</a>のボタンを使用して、表示するマーカーを制御できます:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13238/perf-markers.png" style="display: block; height: 694px; margin-left: auto; margin-right: auto; width: 799px;"></p> + +<h2 id="Waterfall_patterns" name="Waterfall_patterns">タイムラインのパターン</h2> + +<p>タイムラインがどう見えるかは、サイトで行っていることの種類に強く依存します。JavaScript を多く使用するサイトでは橙色が多く表示され、視覚的に動的なサイトでは紫色や緑色が多くなるでしょう。それでもパフォーマンスの問題がある可能性を警告する、一般的なパターンがあります。</p> + +<h3 id="Rendering_waterfall" name="Rendering_waterfall">タイムラインの描画</h3> + +<p>タイムラインビューでよく見るパターンは、以下のようなものです:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10711/perf-timeline-waterfall.png" style="display: block; height: 286px; margin-left: auto; margin-right: auto; width: 727px;"></p> + +<p>これは、ブラウザがイベントへの応答としてページの更新を行うときの基本的なアルゴリズムを視覚しています:</p> + +<ol> + <li><strong>JavaScript 関数呼び出し</strong>: DOM イベントなどのイベントが、ページ内の JavaScript を実行します。JavaScript は、ページの DOM や CSSOM を変更します。</li> + <li><strong>スタイルを再計算</strong>: ページの要素の算出スタイルが変化したとブラウザが判断した場合は、それらを再計算しなければなりません。</li> + <li><strong>レイアウト</strong>: 続いて、要素の位置や形状を計算するために算出スタイルを使用します。この操作は "レイアウト" と名付けられていますが、"リフロー" とも呼ばれます。</li> + <li><strong>描画</strong>: そして、ブラウザはスクリーンに要素を再描画しなければなりません。最後のステップはこの流れで示していません。ページは複数のレイヤーに分割され、それぞれを独立して描画した後に、"コンポジション" と呼ばれるプロセスで合成されます。</li> +</ol> + +<p>この流れが完了しなければスクリーンを更新できませんので、ひとつのフレーム内に一連の操作を収めなければなりません。毎秒 60 フレームが、アニメーションがスムーズに見えるレートとして広く受け入れられています。毎秒 60 フレームのレートのために、ブラウザが一連の操作を実行する時間として 16.7 ミリ秒が与えられます。</p> + +<p>応答性のために重要なこととして、ブラウザは必ずしもすべてのステップを通らなければならないわけではありません:</p> + +<ul> + <li><a href="/ja/docs/Web/Guide/CSS/Using_CSS_animations">CSS アニメーション</a>は JavaScript を実行する必要なくページを更新します。</li> + <li>変更してもリフローを発生させない CSS プロパティがあります。オブジェクトの形状や位置を変更できるプロパティ、例えば <code><a href="/ja/docs/Web/CSS/width">width</a></code>、<code><a href="/ja/docs/Web/CSS/display">display</a></code>、<code><a href="/ja/docs/Web/CSS/font-size">font-size</a></code>、<code><a href="/ja/docs/Web/CSS/top">top</a></code> などを変更すると、リフローが発生します。一方、形状や位置を変更しないプロパティ、例えば <code><a href="/ja/docs/Web/CSS/color">color</a></code> や <code><a href="/ja/docs/Web/CSS/opacity">opacity</a></code> などを変更してもリフローは発生しません。</li> + <li>変更しても再描画を発生させない CSS プロパティがあります。特に <code><a href="/ja/docs/Web/CSS/transform">transform</a></code> プロパティを使用して要素をアニメーションさせる場合、ブラウザはトランスフォームを行う要素を別のレイヤーに分離して、要素が移動しても再描画を行う必要がなくなります。要素の新しい位置は、コンポジションで制御されます。</li> +</ul> + +<p><a href="/ja/docs/Tools/Performance/Scenarios/Animating_CSS_properties">CSS プロパティのアニメーション</a>の記事では、さまざまな CSS プロパティのアニメーションによるパフォーマンスの違いを示すとともに、タイムラインがそれらをどのように知らせるかを説明します。</p> + +<h3 id="Blocking_JavaScript" name="Blocking_JavaScript">妨害する JavaScript</h3> + +<p>デフォルトで JavaScript を実行するスレッドは、ブラウザがレイアウトの更新、再描画、DOM イベントなどに使用するスレッドと同じです。これは、長い間実行する JavaScript 関数が不応答性 (jank) を引き起こす可能性があるということです。アニメーションがぎこちない、あるいはサイトがフリーズするでしょう。</p> + +<p>フレームレートツールとタイムラインを組み合わせると、長い間実行する JavaScript が応答性の問題を引き起こしていることが簡単にわかります。以下のスクリーンショットでは、フレームレートの落ち込みを引き起こしている JS 関数を拡大表示しています:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10973/perf-js-blocking-waterfall.png" style="display: block; height: 432px; margin-left: auto; margin-right: auto; width: 1128px;"></p> + +<p><a href="/ja/docs/Tools/Performance/Scenarios/Intensive_JavaScript">集約的な JavaScript</a> の記事では、長大な JavaScript 関数によって引き起こされる応答性の問題をタイムラインがどのように目立たせるか、またメインスレッドの応答性を維持するために非同期メソッドをどのように使用できるかを説明します。</p> + +<h3 id="Expensive_paints" name="Expensive_paints">高コストな描画</h3> + +<p><code><a href="/ja/docs/Web/CSS/box-shadow">box-shadow</a></code> など負担が大きい描画効果があり、特に毎フレーム計算が必要なトランジションに適用した場合に顕著です。特に、グラフィックを集中的に扱う操作でフレームレートの落ち込みがみられる場合は、タイムラインで緑色のマーカーがないか確認してください。</p> + +<h3 id="Garbage_collection" name="Garbage_collection">ガベージコレクション</h3> + +<p>タイムラインで赤色のマーカーはガベージコレクション (GC) のイベントを表しており、このとき <a href="/ja/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> (Firefox の JavaScript エンジン) は到達不能なメモリを探すためにヒープを確認して、そのようなメモリを解放します。GC を実行している間は JavaScript エンジンを一時停止しなければならないので、プログラムが休止して完全に応答しない状態になるため、GC はパフォーマンスと関係性があります。</p> + +<p>一時停止する時間を短縮するため、SpiderMonkey は<em>インクリメンタル GC</em> を実装しています。これはガベージコレクションを少しずつ実行でき、合間にプログラムを実行することが可能になります。それでも時にはノンインクリメンタルガベージコレクションが必要であり、この場合プログラムは完了するまで待たなければなりません。</p> + +<ul> +</ul> + +<p>GC イベント、特にノンインクリメンタル GC イベントを避けようとして、特定の JavaScript エンジンの実装に最適化しようとすることは賢くありません。SpiderMonkey は GC がいつ必要か、および特にノンインクリメンタル GC がいつ必要かを検出するために、複雑に組み合わせた発見方法を使用しています。ただし、一般に以下のことが言えます:</p> + +<ul> + <li>GC は多くのメモリが割り当てられているときに必要です。</li> + <li>ノンインクリメンタル GC は通常、SpiderMonkey がインクリメンタル GC の実行中にメモリ不足になる可能性があるほどメモリ使用量が高いときに発生します。</li> +</ul> + +<p>タイムラインで GC マーカーを記録するときは、以下の情報を示します:</p> + +<ul> + <li>GC がインクリメンタルか否か</li> + <li>GC を実行した理由</li> + <li>ノンインクリメンタル GC である場合は、インクリメンタルではない理由</li> + <li>Firefox 46 より、GC イベントがメモリ割り当ての圧力によって発生した場合は、"Show Allocation Triggers" というリンクを表示します。このリンクをクリックすると、GC イベントの原因になったメモリ割り当てのプロファイルを表示します。詳しくは<a href="/ja/docs/Tools/Performance/Allocations#Allocations_and_garbage_collection">メモリ割り当てとガベージコレクション</a>をご覧ください。</li> +</ul> + +<h2 id="Adding_markers_with_the_console_API" name="Adding_markers_with_the_console_API">console API でマーカーを追加する</h2> + +<p><a href="/ja/docs/Web/API/Console">console API</a> を呼び出すことで直接制御できるマーカーが 2 つあります。"コンソール" と "Timestamp" です。</p> + +<h3 id="Console_markers" name="Console_markers">コンソールマーカー</h3> + +<p>これは、記録内の特定のセクションにマークをつけるものです。</p> + +<p>コンソールマーカーを作成するにはセクションの始めで <code>console.time()</code> を、セクションの終わりで <code>console.timeEnd()</code> を呼び出します。これらの関数は、セクションの名前として使用される引数を取ります。</p> + +<p>例えば、以下のようなコードで考えてみましょう:</p> + +<pre class="brush: js">var iterations = 70; +var multiplier = 1000000000; + +function calculatePrimes() { + + console.time("calculating..."); + + var primes = []; + for (var i = 0; i < iterations; i++) { + var candidate = i * (multiplier * Math.random()); + var isPrime = true; + for (var c = 2; c <= Math.sqrt(candidate); ++c) { + if (candidate % c === 0) { + // not prime + isPrime = false; + break; + } + } + if (isPrime) { + primes.push(candidate); + } + } + + console.timeEnd("calculating..."); + + return primes; +}</pre> + +<p>タイムラインの出力は、以下のようになります:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10967/perf-console-time.png" style="display: block; height: 430px; margin-left: auto; margin-right: auto; width: 1192px;"></p> + +<p>マーカーは <code>console.time()</code> に渡した引数で名付けられており、マーカーを選択すると右側のサイドバーでプログラムスタックを確認できます。</p> + +<h4 id="Async_stack" name="Async_stack">Async stack</h4> + +<p class="geckoVersionNote">Firefox 41 の新機能</p> + +<p>Firefox 41 より、右側のサイドバーに終了時点、すなわち <code>console.timeEnd()</code> を呼び出した時点のスタックも表示します。<code>console.timeEnd()</code> が <code><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code> の成功によって呼び出された場合は、"(非同期: Promise)" と表示します。これは "async stack" を表すものであり、その時点のコールスタックで promise が生成されています。</p> + +<p>例えば、以下のコードで考えてみましょう:</p> + +<pre class="brush: js">var timerButton = document.getElementById("timer"); +timerButton.addEventListener("click", handleClick, false); + +function handleClick() { + console.time("timer"); + runTimer(1000).then(timerFinished); +} + +function timerFinished() { + console.timeEnd("timer"); + console.log("ready!"); +} + +function runTimer(t) { + return new Promise(function(resolve) { + setTimeout(resolve, t); + }); +}</pre> + +<p>タイムラインでは <code>time()</code> と <code>timeEnd()</code> の間をマーカーで表示します。このマーカーを選択すると、サイドバーに async stack が表示されるでしょう:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11179/async-stack.png" style="display: block; height: 378px; margin-left: auto; margin-right: auto; width: 352px;"></p> + +<h3 id="Timestamp_markers" name="Timestamp_markers">Timestamp マーカー</h3> + +<p>タイムスタンプで、記録中にその場でマークすることができます。</p> + +<p>タイムスタンプマーカーを作成するには、<code><a href="/ja/docs/Web/API/Console/timeStamp">console.timeStamp()</a></code> を呼び出します。タイムスタンプのラベルを引数として渡すことができます。</p> + +<p>例えば前出のコードで繰り返し 10 回ごとにタイムスタンプを生成して、繰り返し回数を名前として付加します:</p> + +<pre class="brush: js">var iterations = 70; +var multiplier = 1000000000; + +function calculatePrimes() { + console.time("calculating..."); + + var primes = []; + for (var i = 0; i < iterations; i++) { + + if (i % 10 == 0) { + console.timeStamp(i.toString()); + } + + var candidate = i * (multiplier * Math.random()); + var isPrime = true; + for (var c = 2; c <= Math.sqrt(candidate); ++c) { + if (candidate % c === 0) { + // not prime + isPrime = false; + break; + } + } + if (isPrime) { + primes.push(candidate); + } + } + console.timeEnd("calculating..."); + return primes; +}</pre> + +<p>タイムラインは以下のようになります:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10971/perf-timestamp.png" style="display: block; height: 530px; margin-left: auto; margin-right: auto; width: 1192px;"></p> |