デタッチされた要素ツールを使用して DOM メモリ リークをデバッグする
デタッチされた要素ツールは、切断されたすべての要素を Web ページで見つけて表示する 1 つの方法です。 メモリ リークを評価するその他の方法については、「メモリの問題を修正する」の「デタッチされた要素を調査するためのツール」を参照してください。
重要
デタッチされた要素ツールは非推奨です。 Microsoft Edge 130 以降、 デタッチされた要素 ツールには、ツールが非推奨であることを示すメッセージが表示されます。代わりに、 メモリ ツールの [プロファイルの種類の 選択 ] 画面で、[ デタッチされた要素 ] オプション ボタンを選択します。 Edge 専用 Chrome DevTools Protocol (CDP) 関数 EdgeDOMMemory.getDetachedNodesIds
は引き続き機能しますが、代わりに を使用 DOM.getDetachedDomNodes
します。
Microsoft Edge 133 では、 デタッチされた要素 ツールが削除されます。代わりに、 メモリ ツールの [プロファイルの種類の 選択 ] 画面で、[ デタッチされた要素 ] オプション ボタンを選択します。 CDP 関数 EdgeDOMMemory.getDetachedNodesIds
は削除されます。代わりに を使用 DOM.getDetachedDomNodes
します。
Web ページのパフォーマンスを向上させるには、DOM ツリーからデタッチされ、JavaScript コードで引き続き参照されるとは思わなかった要素を見つけます。 コードが引き続き参照しているため、ブラウザーでガベージ コレクションできないデタッチされた要素を見つけて、デタッチされた要素への JavaScript コード参照を解放します。
[デタッチされた要素] ツール。メモリ ツールにリテーナーが表示され、ソース ツールで JavaScript コードを開くリンクが表示されます。
ビデオ: Microsoft Edge デタッチされた要素ツールを使用してメモリ リークをデバッグする
デタッチされた要素ツールを使用してメモリ リークを修正する方法
- 分析する Web ページを開きます。
- デタッチされた要素ツールを開きます。
- ガベージ コレクションを実行し、JavaScript オブジェクトによって参照されなくなったすべてのノードを削除します。
- ガベージ コレクションできなかったデタッチされたすべての要素を取得します。
- デタッチされた特定の要素とその JavaScript を分析して、ツリー全体が保持される原因となっているデタッチされたツリー内の原因となるノードを特定します。
デタッチされた要素を取得し、デタッチされた要素の JavaScript を分析する
デタッチされた要素のデモ Web ページを使用して デタッチされた要素 を分析するには:
デタッチ された要素のデモ Web ページ を新しいウィンドウまたはタブで開きます。
[ Room 1 ] ボタンが最初に選択されています。 デモ Web ページの JavaScript コードでは、クラスのインスタンスを
Room
使用して Room 1 のメッセージを管理します。Web ページを右クリックし、[ 検査] を選択します。 または、 Ctrl + Shift + I (Windows、Linux) または Command + Option + I (macOS) を押します。
DevTools が開きます。
DevTools の アクティビティ バーで、[ デタッチされた要素] ([デタッチされた要素 ] ) タブを選択します。そのタブが表示されない場合は、[ その他のツール ] () ボタンをクリックするか、DevTools の幅を広げます。 デタッチされた要素ツールが開きます。
Room クラスの JavaScript インスタンスによって格納されるメッセージを生成します。
デモ Web ページで、[ 高速トラフィック ] ボタンをクリックします。
デモ Web ページでは、メッセージの生成と Web ページへの表示が開始されます。
一部のメッセージが表示されたら、デモ Web ページの [停止 ] ボタンをクリックします。
各メッセージは、
<div class="message">
クラスの Room 1 インスタンスRoom
によって参照される要素です。 Web ページ DOM ツリーにはデタッチされた要素はありません。すべてのメッセージ要素が Room クラスの現在の Room 1 インスタンスにアタッチされているためです。Room クラスの別のインスタンスに変更すると、要素がデタッチされます。
デモ Web ページで、クラスの別のインスタンスに対応する [会議室 2 ] ボタンを
Room
クリックします。Web ページでは、メッセージは消えます。
Room クラス (
<div class="message">
要素) の Room 1 インスタンスに対して生成されたメッセージは DOM にアタッチされなくなりましたが、Room クラスの Room 1 インスタンスによって引き続き参照されます。 これらはデタッチされた要素であり、Web ページで再度使用しない限り、メモリ リークを引き起こす可能性があります。デタッチされた要素の一覧を取得します。
DevTools の デタッチされた要素 ツールで、[ ガベージの収集 ] アイコン () をクリックします。
ブラウザーはガベージ コレクションを実行し、JavaScript オブジェクトによって参照されなくなったノードを削除します。
[デタッチされた要素] ツールで、[デタッチされた要素の取得] ([) ボタンをクリックします。
ガベージ コレクションできないデタッチされた DOM 要素が表示されます。
これらのデタッチされた要素は、アプリケーションによって再利用されない場合のメモリ リークです。
特定のデタッチされた要素を参照する JavaScript コードを特定します。
[デタッチされた要素] ツールで、[分析] ([分析] ) ボタンをクリックします。
デタッチされた要素ツールの下部に、メモリ ヒープの取得スナップショット. というメッセージが簡単に表示され、[すべて完了] というメッセージが表示されます。 メモリ ツールは、DevTools の下部にあるクイック ビュー パネルで開きます。
[概要] と [保持者] UI の代わりに [メモリ] ツールに [プロファイルの種類] オプション ボタンが表示されている場合は、もう一度 [分析] () ボタンをクリックします。
[デタッチされた要素] ツールの [Id] 列で、@21299 や @21783 などの ID をダブルクリックします。
これは、メモリ ヒープ スナップショット内のいずれかの
<div class="message">
要素の一意識別子です。 [メモリ] ツールの [リテーナー] タブにリテーナーが表示されます。メモリ ツールは、デタッチされた要素を参照しているヒープ内のオブジェクトを自動的に選択します。 このようなオブジェクトはリ テーナーと呼ばれます。
[ 保持者 ] タブのメンバーに関する
unmounted
リテーナー サブエントリ ( Room @54011 でマウント解除など) で、 リンクroom.js:13 をクリックします。[ソース] ツールがアクティビティ バーで開き、ファイル room.js (コンストラクター) の 13 行目が
Room
表示されます。unmounted
は クラスのRoom
配列メンバーで、コンストラクターの 19 行目で定義されています。this.unmounted = [];
クラスの メソッド内
hide
の 49this.unmounted.push(el);
行目まで下にRoom
スクロールします。コードは、ルーム内の各メッセージを配列に
unmounted
追加します。 配列はunmounted
、デタッチされた要素を参照しているオブジェクトです。
JavaScript コードでは、デタッチされた要素がブラウザーによってガベージ コレクションされるのを妨げているリテーナー オブジェクト ( unmounted
配列) を特定しました。
ブラウザーでガベージ コレクションできないデタッチされた要素が見つかり、デタッチされた要素をまだ参照している JavaScript オブジェクトが見つかりました。 その後、JavaScript コードを変更して要素を解放し、Web ページ上のデタッチされた要素の数を減らし、Web ページのパフォーマンスと応答性を向上させることができます。
他の DOM ノードが保持される原因となっている DOM ノードを特定する
DOM は完全に接続されたグラフであるため、1 つの DOM ノードが JavaScript によってメモリに保持されると、他の DOM ノードが保持される可能性があります。
ツリー全体が保持される原因となっているデタッチツリー内の原因となるノードを特定するには:
[ 要素のデタッチ ] (をクリックして、デタッチされたツリー内の親子リンクを破棄します。
[ ガベージの収集 ] アイコン (クリックします。
親子リンクはデタッチされたツリー内で削除され、残りの項目は他の DOM ノードが保持される原因となった DOM ノードです。
選択したターゲットを別の配信元に変更する
[選択したターゲット] ドロップダウン リストを使用して、さまざまな配信元またはフレームからデタッチされた要素をチェックするには:
[ 選択したターゲット ] ドロップダウン リストをクリックします。
別の配信元を選択します。
新しい原点は、[ デタッチされた要素 ] ツールに表示されます。
デタッチされた要素とメモリ リークについて
デタッチされた要素は必ずしもメモリ リークを示すわけではありません。また、メモリ リークはデタッチされた要素によって常に発生するとは限りません。 メモリ リークは、アプリケーションのコンテキストによって異なります。
メモリ リークは、要素がドキュメント オブジェクト モデル (DOM) ツリーにアタッチされなくなったが、Web ページで実行されている一部の JavaScript によって引き続き参照されている場合に、アプリケーションで発生する可能性があります。 これらの要素はデタッチ された要素と呼ばれます。 ブラウザーがデタッチされた要素をガベージ コレクション (GC) するには、DOM ツリーまたは JavaScript コードから要素を参照することはできません。
メモリの問題は、メモリ リーク、メモリの膨らみ、頻繁なガベージ コレクションなど、Web ページのパフォーマンスに影響します。 ユーザーの症状は次のとおりです。
- Web ページのパフォーマンスは、時間の経過と同時に徐々に悪化します。
- Web ページのパフォーマンスは一貫して悪いです。
- Web ページのパフォーマンスが遅れているか、頻繁に一時停止しているように見えます。
デタッチされた要素を取得する前に GC を実行して、GC'd にできない要素のみを表示する
DOM ツリーからデタッチされ、ガベージ コレクションできない要素のみを表示するには、常に [ ガベージの収集 ] を最初にクリックし、[ デタッチされた要素の取得] をクリックします。
一部の要素は一度にデタッチされた状態で表示される場合がありますが、GC を実行するまで、Web ページの JavaScript コードによって実際に参照されているかどうかはわかりません。 デモ アプリでチャット ルームを切り替えると、Web ページは DOM からメッセージを表示するために使用される要素を削除します。 ただし、クラスの別の Room
インスタンスに切り替えると、これらの要素が完全に削除されるわけではなく、これらの要素への参照がまだ存在するため、これらの要素はメモリ内に残ります。
要素を再アタッチする
デタッチされた要素のデモ Web ページでは、チャット メッセージの一覧を保持して、ユーザーが Room 1 に戻った場合にメッセージ ログが保持されるようにするのが理にかなっています。 同様に、ソーシャル メディアのフィードは、ユーザーが要素をスクロールしたときに要素を切り離し、ユーザーがスクロールして戻るときに DOM に再アタッチする場合があります。
デタッチされた要素ツールがデタッチされた要素を報告する場合、必ずしもメモリ リークとは限りません。 メモリ リークとは何か、そうでないものを決めるのはあなた次第です。 おそらく、アプリは後でそれらの要素をアタッチし直します (作成し直す必要が生じず、遅くなる可能性があります)。
DOM ノードのデタッチは、最終的にそれらのデタッチされた要素を再利用する (または削除する) 限り、便利な方法です。 デタッチされた要素ツールの値は、メモリ リークが疑われる場合に、ツールによって報告される予期しないデタッチされた DOM 要素の数が増えているかどうかをチェックできます。
実行時間の長いアプリとコンポーネントのマウント解除
コンポーネントのマウントを解除してください。 実行時間の長いアプリでは、わずか数キロバイトの小さなメモリ リークによって、時間の経過と同時にパフォーマンスが著しく低下する可能性があります。 React フレームワークを使用する Web ページの場合、Reactは DOM の仮想化されたコピーを保持します。 コンポーネントのマウントを適切に解除できないと、アプリケーションが仮想 DOM の大部分をリークする可能性があります。
問題の報告
デタッチされた要素機能のしくみに関する問題が発生した場合は、Microsoft Edge DevTools チームに問い合わせて、デタッチされた要素機能とメモリ リーク デバッグに関するフィードバックを送信してください。
関連項目
- 「メモリの問題を修正する」 のデタッチされた要素を調査するためのツール - デタッチされた要素を表示するためのツールの比較。
デモ:
- デタッチされた要素のデモ Web ページ
- MicrosoftEdge/Demos > detached-elements リポジトリ フォルダー - ソース コード。