Worker が CPU 負荷の高い処理に時間を使いすぎると、レスポンスが遅くなることがあります。また、時間制限 により Worker の起動に失敗することもあります。
DevTools のプロファイリングを使うと、CPU を使いすぎているコードを特定して修正できます。
本番環境では、セキュリティ上の理由で Workers が I/O のときだけタイマーを進める ため、特定関数の実行時間を測るのは難しいです。一方、ローカル開発では DevTools を使って CPU 実行時間を計測できます。
DevTools で CPU 使用量を監視するとき、本番で見ている特定の挙動を再現しづらいことがあります。本番に近づけるには、ローカル Worker へ送るリクエストを本番のリクエストに似せます。大量のリクエストを送る、特定ルートへリクエストする、リモートバインディング で本番に近いデータを使う、といった方法があります。
CPU プロファイルを生成する手順は次のとおりです。
wrangler devを実行して Worker を起動します- ターミナルで
Dキーを押し、DevTools を開きます - 「Profiler」タブを選択します
Startを選択して、CPU 使用量の記録を開始します- 新しいタブから Worker へリクエストを送ります
Stopを選択します
これで CPU プロファイルが得られます。
CPU プロファイルの読み方を、例で確認します。次のような Worker があるとします。
const addNumbers = (body) => {
for (let i = 0; i < 5000; ++i) {
body = body + " " + i;
}
return body;
};
const moreAddition = (body) => {
for (let i = 5001; i < 15000; ++i) {
body = body + " " + i;
}
return body;
};
export default {
async fetch(request, env, ctx) {
let body = "Hello Profiler! - ";
body = addNumbers(body);
body = moreAddition(body);
return new Response(body);
},
};レスポンスが遅くなる原因を特定したいとします。DevTools のプロファイリングで、CPU 負荷の高いコードを見つけて修正するにはどうすればよいでしょうか。
まず、前述のとおり wrangler dev の実行後に D キーで DevTools を開きます。次に「Profiler」タブへ移動し、Start を押してリクエストを送り、プロファイルを取得します。
上のグラフはプロファイルのタイムラインです。特定のリクエストにズームインできます。
下のグラフは、そのリクエスト中に実行された処理の CPU 時間です。このスクリーンショットでは、先頭に "fetch" の時間があり、その下に addNumbers と moreAdditions の 2 つの関数を含むサブコンポーネントがあります。各ボックスにカーソルを置くと詳細が表示され、ボックスをクリックすると関数のソースコードへ移動します。
このグラフで「何が CPU 時間を使っているか」に答えられます。addNumbers のボックスは小さく、CPU 時間は 0.3ms です。moreAdditions のボックスは大きく、CPU 時間は 2.2ms です。
したがって、レスポンスを速くするには moreAdditions を最適化する必要があります。
表示を ‘Chart’ から ‘Heavy (Bottom Up)’ に切り替えると、別の見方もできます。
各関数に割り当てられた相対時間を示します。リストの先頭で、moreAdditions が Worker の中で明らかに最も遅い部分です。ガベージコレクションも大きな割合を占めるので、メモリ最適化が有効な場合があります。
CPU プロファイラーの使い方の詳細は、Google の DevTools での CPU プロファイリングに関するドキュメント ↗ を参照してください。
メモリの把握に DevTools を使う方法は、メモリ使用量のドキュメント を参照してください。