Internet Explorer 10 で Web ワーカーをデバッグする

本記事は、マイクロソフト本社の IE チームのブログ から記事を抜粋し、翻訳したものです。 

【元記事】Debugging Web Workers in IE10 (2011/7/13 3:34 AM)

Web ワーカーを使用すると、実行時間が長く複雑な JavaScript アルゴリズムをオフロードしてバックグラウンドで実行することにより、Web アプリケーションの応答性を向上させることができます。Internet Explorer 10 には、Web ページおよび Web ワーカー内で実行される JavaScript に対して、総合的で予測可能なデバッグ環境が用意されています。

IE10 では、すべての Web ワーカーについて作成される新しいスクリプト コンテキストに対応するため、F12 ツールが強化されました。デバッグを開始 (F12 ツールの [デバッグ開始] ボタンをクリック) すると、Web ページのスクリプト コンテキストおよび現在実行中の (または後で実行される) ワーカーのコンテキストにアタッチできます。

これが上に述べた “総合的で予測可能なデバッグ” です。F12 ツールが備える、従来の単一スレッド スクリプトで利用可能なスクリプト デバッグ機能やプロファイル機能はすべて、ワーカーについても同様に使用できます。これを使用しない場合、エミュレーションを使用して限られたデバッグ機能のみをサポートする方法があります。

現在、多くの開発者ツールでは、Web ワーカーのデバッグが一切サポートされていませんが、一部のツールは、シミュレートされた環境 (iframe を使用してワーカーをエミュレートした環境など) に限定したデバッグ機能を提供しています。残念ながら、こうしたシミュレーション環境では、通常の実行ではエラーになるような無効なシナリオ (DOM アクセスなど) が、デバッグでは成功してしまい、開発者が判断を誤る可能性があります。

実行時の動作を忠実に再現しないデバッガーを使用すると、特に既存のコードをワーカー用に移行するような場合に、見落としやすい "ハイゼンバグ" が発生していた、ということになりがちです。さらに、シミュレートされた環境は UI のスレッド コンテキストで実行されるため、デバッグ時にアプリケーションが応答を停止する危険性があります。この 2 つの潜在的な欠陥を考えると、やはり開発者には、Web ワーカーを使用するアプリケーション用の完全なデバッグ ツールが必要となります。

既存の手法に基づいた各種機能

F12 ツールは、標準的なスクリプトと同様のサポートを Web ワーカーについても提供するので、デバッグ方法の多くは開発者にとって既になじみのあるものです。たとえば、ワーカーの実行スクリプト内でのブレークポイントの設定、ローカル変数の表示、ウォッチの設定、コンソールを介したワーカーの操作、コードのステップ実行などの操作が可能です。これにより、スクリプト デバッグの知識がある開発者は、すぐに Web ワーカーのデバッグを活用できます。ただし、ワーカーのデバッグに関しては、以下に述べるように、いくつか注意すべき点もあります (以下のスクリーン ショットはすべてデモ用アプリケーションの Web Worker Harness for test262 から取得しています)。

スクリプトで新しい Worker オブジェクトが作成され、ワーカーのスクリプト コンテキストが初期化されると、実行中のスクリプト ファイルがスクリプト リソースの一覧に表示されます。ここから、ファイルを選択して、従来と同様にデバッグを開始できます。]

clip_image002
F12 開発者ツールの [スクリプト] タブと使用可能なスクリプトのメニューを示すスクリーン ショット

Web ワーカーのスクリプト内のブレークポイントで停止し、その変数やスコープを詳細にチェックすると、ワーカーのスクリプトと標準的なスクリプトでは、1 つ大きな違いがあることがわかります。ワーカーのスクリプトは、従来の “Window” オブジェクトではなく、WorkerGlobalScope 型のグローバル オブジェクトを使用しているということです。この新しいオブジェクトは、Web ワーカーが UI スレッドと共有されるメモリ (DOM など) にアクセスすることを制約します。そのようなアクセスは、通常の実行時には許可されません。これを確認するには、下のように、self にウォッチを追加します。

F12 開発者ツールの [ウォッチ] タブのスクリーン ショット
F12 開発者ツールの [ウォッチ] タブのスクリーン ショット

複数のスクリプトコンテキストのデバッグ

F12 ツールは現在実行中のすべてのスクリプト コンテキストを認識しているため、ブレークポイントで停止している間は、他のすべてのスクリプト エンジンに対して一時停止を指示できます。これによって、他のスクリプト コンテキストが現在デバッグ中のスクリプト コンテキストと対話することが防止され、予測可能なデバッグ環境が実現します。

さらに、一度に 1 つのスクリプト コンテキストしかデバッグできないという制限もありません。ブレークポイント (ワーカー内または UI スレッド内) から実行を継続すると、すべてのスクリプト コンテキストが再開され、次のブレークポイントに到達するまで (あるいは debugger ステートメントや例外が検出されるまで) 実行できます。このプロセスではワーカーのスクリプト コンテキストから UI スレッドのコンテキストにフォーカスが自動的に切り替わり、コンテキスト間の対話を容易にデバッグできます。

ワーカーを使用するアプリケーション内のブレークポイントで停止している際、[コール スタック] ウィンドウで、(実際のコール スタックに加えて) 実行されているワーカー インスタンスの数を確認できます。各 "Root" は異なる JavaScript 実行コンテキストを表します。“Root #0” は、Web ページの通常のスクリプトを実行する、メインの JavaScript UI スレッドを表します。“Root #1” は現在実行中のワーカーを表します (スクリプト ファイルによって識別可能)。他のワーカーも実行されている場合は、Root #2、Root #3 のように表示されます。

F12 開発者ツールの [コール スタック] タブのスクリーン ショット
F12 開発者ツールの [コール スタック] タブのスクリーン ショット

ワーカーのアクティビティとネットワーク要求のプロファイリング

デバッグに加えて、他のスクリプトと同様に、プロファイラーを使用して実行中のワーカーのパフォーマンスを確認することもできます。F12 ツールで [プロファイラー] タブをクリックし、[プロファイリングの開始] をクリックして、プロファイリング対象のスクリプトを実行します。完了したら、F12 ツールの [プロファイリングの停止] をクリックします。次の図は、[現在のビュー] ドロップダウン リストで [呼び出しツリー] を選択したところです。

F12 開発者ツールの [プロファイラー] タブのスクリーン ショット
F12 開発者ツールの [プロファイラー] タブのスクリーン ショット

[URL] 列に、個々のアクティビティの基となるスクリプトの所在が示されています。この画面から、たとえばこのテストをワーカー内で実行した場合 (ワーカー内の “execute” 関数) にかかる時間は、UI スレッドで実行した場合 (UI スレッド内の “run” 関数) にかかる時間よりも短いことがわかります。

ワーカーはネットワーク全体のアクティビティにも影響を与えます。ブラウザーに、ワーカーが実行するスクリプトと、関連するすべての子スクリプトを (importScripts メソッドを通じて) ダウンロードする必要があるためです。この操作は、[ネットワーク] タブをクリックして、[キャプチャの開始] ボタンをクリックするだけで実行できます。ワーカーが開始したスクリプト要求を含むキャプチャのスクリーン ショットを以下に示します。

clip_image002[7]
F12 開発者ツールの [ネットワーク] タブのスクリーン ショット

上の画像では、“worker.js” ファイルのダウンロード要求が表示されています。さらに興味深いのは、[イニシエーター] 列に、このファイルのダウンロードが何によって開始されたか (ここでは Web ワーカー) が示されている点です。また、"15.2.js” ファイル (ワーカーによってインポートされたもの) も表示され、importScripts メソッドの呼び出しによって開始されたことが示されています。

マイクロソフトでは、皆様からのフィードバックをお待ちしています。IE10 での Web ワーカーの使用について、または関連ツールについてお気づきの点があれば、Connect からご報告ください。

—Jonathan Carter、Gaurav Seth
プログラム マネージャー、ブラウザー プログラマビリティ & ツール