はじめに
現在、作成者は多くの抽象化を使用してウェブ アプリケーションを構築できます。多くの作成者は、ウェブ プラットフォームが提供する低レベル API と直接やり取りするのではなく、フレームワーク、ビルドツール、コンパイラを活用して、より高いレベルの視点からアプリケーションを記述します。
たとえば、Angular フレームワーク上に構築されたコンポーネントは、HTML テンプレートを使用して TypeScript で作成されます。内部では Angular CLI と webpack によってすべてが JavaScript にコンパイルされ、いわゆる「バンドル」にまとめられます。バンドルはブラウザに送られます。
現在、DevTools でウェブ アプリケーションをデバッグまたはプロファイリングする場合、実際に記述したコードではなく、このコンパイル済みバージョンのコードが表示され、デバッグできます。ただし、著者としては望ましいことではありません。
- 圧縮された JavaScript コードをデバッグするのではなく、元の JavaScript コードをデバッグする場合。
- TypeScript を使用する場合は、JavaScript ではなく、元の TypeScript コードをデバッグする必要があります。
- Angular、Lit、JSX などのテンプレートを使用する場合、生成された DOM をデバッグする必要がない場合があります。コンポーネント自体をデバッグする必要がある場合。
全体的に、独自のコードを作成したときと同じようにデバッグすることをおすすめします。
ソースマップはすでにこのギャップをある程度埋めていますが、Chrome DevTools とエコシステムが実現できるこの領域はまだまだあります。
早速見てみよう。
作成されたコードとデプロイされたコード
現在、[ソースパネル] でファイルツリーを操作すると、コンパイルされた(多くの場合、圧縮された)バンドルの内容が表示されます。これらは、ブラウザがダウンロードして実行する実際のファイルです。DevTools では、これを「デプロイされたコード」と呼びます。
これはあまり便利ではなく、把握しづらいことがよくあります。作成者は、デプロイされたコードではなく、作成したコードを表示してデバッグする必要があります。
これを補うため、代わりに作成元のコードをツリーに表示できるようになりました。これにより、ツリーは IDE で表示されるソースファイルに近づき、これらのファイルは [デプロイされたコード] から分離されました。
Chrome DevTools でこのオプションを有効にするには、[設定] > [試験運用版] に移動し、[ソースを作成済みツリーとデプロイ済みツリーにグループ化] をオンにします。
[自分のコードのみ]
依存関係を使用する場合やフレームワーク上にビルドする場合、サードパーティ ファイルが邪魔になることがあります。ほとんどの場合、node_modules
フォルダに隠れているサードパーティ ライブラリのコードではなく、自分のコードのみを表示する必要があります。
これを補うため、DevTools にはデフォルトで追加の設定(既知のサードパーティ スクリプトを無視リストに自動追加)が有効になっています。これは、[DevTools] > [Settings] > [Ignore List] で確認できます。
この設定を有効にすると、フレームワークまたはビルドツールが「無視する」とマークしたファイルまたはフォルダが DevTools で非表示になります。
Angular v14.1.0 以降、node_modules
フォルダと webpack
フォルダの内容には、そのようにマークが付けられています。そのため、これらのフォルダ、その中のファイル、その他のサードパーティ アーティファクトは、DevTools のさまざまな場所に表示されません。
著者側でこの新しい動作を有効にするための操作は必要ありません。この変更を実装するのはフレームワーク次第です。
スタック トレース内の無視リストに登録されたコード
無視リストに登録されたファイルが、スタック トレースには表示されなくなりました。作成者は、より関連性の高いスタック トレースを確認できるようになりました。
スタック トレース内のすべての呼び出しフレームを表示するには、[Show more frames] リンクをクリックします。
コードのデバッグとステップスルー中に表示されるコールスタックにも同じことが言えます。フレームワークまたはバンドラがサードパーティ スクリプトについて DevTools に通知すると、DevTools は関連のない呼び出しフレームをすべて自動的に非表示にし、ステップ デバッグ中に無視リストに登録されたコードを飛ばします。
ファイルツリー内の無視リストに登録されたコード
無視リストに登録されたファイルとフォルダを [ソース] パネルの [作成者コード] ファイルツリーから非表示にするには、DevTools の [設定] > [試験運用版] で [ソースツリービューで無視リストに登録されたコードを非表示にする] をオンにします。
サンプルの Angular プロジェクトでは、node_modules
フォルダと webpack
フォルダが非表示になりました。
[クイック開く] メニューの無視リストに登録されたコード
無視リストに登録されたコードは、ファイルツリーから非表示になるだけでなく、[クイック開く] メニュー(Ctrl+P(Linux / Windows)または Command+P(Mac))からも非表示になります。
スタック トレースのさらなる改善
関連性の高いスタック トレースはすでにカバーされていますが、Chrome DevTools ではスタック トレースがさらに改善されています。
リンクされたスタック トレース
一部のオペレーションが非同期的に実行されるようにスケジュールされている場合、DevTools のスタック トレースでは現時点で一部の情報しかわかりません。
たとえば、架空の framework.js
ファイル内の非常にシンプルなスケジューラを次に示します。
function makeScheduler() {
const tasks = [];
return {
schedule(f) {
tasks.push({ f });
},
work() {
while (tasks.length) {
const { f } = tasks.shift();
f();
}
},
};
}
const scheduler = makeScheduler();
function loop() {
scheduler.work();
requestAnimationFrame(loop);
};
loop();
デベロッパーが example.js
ファイルの独自のコードで使用する方法は次のとおりです。
function someTask() {
console.trace("done!");
}
function businessLogic() {
scheduler.schedule(someTask);
}
businessLogic();
someTask
メソッド内にブレークポイントを追加した場合や、コンソールに出力されたトレースを調べた場合、このオペレーションの「根本原因」である businessLogic()
呼び出しに関する記述は見つかりませんでした。
タスク実行につながったフレームワーク スケジューリング ロジックのみが表示され、スタック トレースにはパンくずリストが表示されないため、このタスクに至るイベント間の因果関係を把握するのに役立ちます。
「非同期スタック タグ付け」という新機能により、非同期コードの両方の部分をリンクすることで、全体像を把握できるようになりました。
Async Stack Tagging API に、console.createTask()
という新しい console
メソッドが導入されました。API シグネチャは次のとおりです。
interface Console {
createTask(name: string): Task;
}
interface Task {
run<T>(f: () => T): T;
}
console.createTask()
呼び出しは Task
インスタンスを返します。このインスタンスは、後でタスクのコンテンツ f
の実行に使用できます。
// Task Creation
const task = console.createTask(name);
// Task Execution
task.run(f);
タスクは、作成されたコンテキストと実行中の非同期関数のコンテキストをリンクします。
上記の makeScheduler
関数に適用すると、コードは次のようになります。
function makeScheduler() {
const tasks = [];
return {
schedule(f) {
const task = console.createTask(f.name);
tasks.push({ task, f });
},
work() {
while (tasks.length) {
const { task, f } = tasks.shift();
task.run(f); // instead of f();
}
},
};
}
これにより、Chrome DevTools でより正確なスタック トレースを表示できるようになりました。
businessLogic()
がスタック トレース内に含まれていることに注目してください。それだけでなく、タスクには、以前の一般的な requestAnimationFrame
ではなく、わかりやすい名前 someTask
が付けられます。
フレンドリーな呼び出しフレーム
フレームワークは、プロジェクトの構築時にさまざまなテンプレート言語からコードを生成します。たとえば、Angular や JSX テンプレートでは、HTML に似たコードを、最終的にブラウザで実行される単純な JavaScript に変換します。生成されたこのような関数の中には、あまり親しみのない名前が付けられることもあります。たとえば、圧縮された後に 1 文字の名前であったり、そうでなくても不明瞭な名前やなじみのない名前であったりします。
サンプル プロジェクトにおけるこの例は、スタック トレースに表示される AppComponent_Template_app_button_handleClick_1_listener
です。
この問題に対処するため、Chrome DevTools ではソースマップを使用してこれらの関数の名前変更がサポートされるようになりました。ソースマップに関数スコープの開始点の名前エントリがある場合、コールフレームはその名前をスタックトレース内に表示します。
著者側でこの新しい動作を有効にするための操作は必要ありません。この変更を実装するのはフレームワーク次第です。
今後に向けて
この投稿で説明した機能の追加により、Chrome DevTools でより快適にデバッグできるようになりました。チームは、他にも検討したい領域があります。特に、DevTools でのプロファイリングの使い勝手を改善する方法について説明します。
Chrome DevTools チームは、フレームワークの作成者にこれらの新機能を導入することを推奨しています。事例紹介: DevTools を使用した Angular デバッグの改善では、この実装方法に関するガイダンスを提供しています。