JSの仕組み:MutationObserverを使用したDOMの変更の追跡

本日、JavaScriptメカニズムの機能に特化したシリーズの10番目の資料の翻訳で、MutationObserver APIを使用してDOMの変更を追跡する方法について説明します。

Webアプリケーションのクライアント部分はより複雑になり、より多くのシステムリソースが必要になります。 これはさまざまな理由で発生します。特に、そのようなアプリケーションには高度なインターフェースが必要であるため、その機能が明らかになり、クライアント側で複雑な計算を実行する必要があるためです。



これらはすべて、ライフサイクルのプロセスでアプリケーションインターフェイスの状態を監視するタスクを複雑にします。 このタスクは、フレームワークや通常のライブラリのようなものを開発する場合、たとえばページで何が起こっているかに反応し、DOMに依存するいくつかのアクションを実行する必要がある場合、さらに大きくなります。

[アドバイスを読む]サイクルの他の19の部分
パート1: エンジン、ランタイムメカニズム、コールスタックの概要
パート2: V8内部とコードの最適化について
パート3: メモリ管理、4種類のメモリリーク、およびそれらとの戦い
パート4: イベントループ、非同期、および非同期/待機を使用してコードを改善する5つの方法
パート5: WebSocketとHTTP / 2 + SSE。 何を選ぶ?
パート6: WebAssemblyの機能と範囲
パート7: Web Workersと5つの使用シナリオ
パート8: サービスワーカー
パート9: Webプッシュ通知
パート10: MutationObserverを使用してDOMの変更を追跡する
パート11: Webページレンダリングエンジンとパフォーマンスを最適化するためのヒント
パート12: パフォーマンスとセキュリティを最適化するブラウザーネットワークサブシステム
パート12: パフォーマンスとセキュリティを最適化するブラウザーネットワークサブシステム
パート13: CSSとJavaScriptを使用したアニメーション
パート14: JSの仕組み:抽象構文ツリー、解析、およびその最適化
パート15: JSの仕組み:クラスと継承、BabelおよびTypeScriptでのトランスピレーション
パート16: JSの仕組み:ストレージ
パート17: JSの仕組み:Shadow DOMテクノロジーとWebコンポーネント
パート18: JSの仕組み:WebRTCおよびP2P通信メカニズム
パート19: JSの仕組み:カスタム要素

復習


MutationObserverは、最新のブラウザーが提供するWeb APIであり、DOMの変更を検出するように設計されています。 このAPIを使用すると、DOMノードの追加または削除、要素の属性の変更、またはテキストノードのテキストの変更などを観察できます。 なぜこれが必要なのですか?

MutationObserver APIが非常に役立つ状況は数多くあります。 例:



ブラウザベースのテキストエディター

上記は、 MutationObserverの機能が役立つ可能性がある状況のほんの一部です。 実際、もっとたくさんあります。

MutationObserverの使用方法


WebアプリケーションでMutationObserverを使用するのは非常に簡単です。 MutationObserverインスタンスを作成し、対応するコンストラクターに関数を渡す必要があります。このコンストラクターは、DOMで変更が発生するたびに呼び出されます。 関数の最初の引数は、単一のパッケージで発生したすべての突然変異のコレクションです。 各突然変異について、そのタイプとそれが表す変化に関する情報が提供されます。

 var mutationObserver = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) {   console.log(mutation); }); }); 

作成されたオブジェクトには3つのメソッドがあります。


変更監視を有効にする方法は次のとおりです。

 //       HTML-  mutationObserver.observe(document.documentElement, { attributes: true, characterData: true, childList: true, subtree: true, attributeOldValue: true, characterDataOldValue: true }); 

ここで、DOMに最も単純なdiv要素があるとします。

 <div id="sample-div" class="test"> Simple div </div> 

jQueryを使用して、この要素からclass属性を削除できます。

 $("#sample-div").removeAttr("class"); 

mutationObserver.observe(...)MutationObserver.observe mutationObserver.observe(...)呼び出して変更の監視を開始したという事実と、新しい変更パッケージに応答する関数は受信したデータをコンソールに表示するため、対応するMutationRecordオブジェクトの内容がコンソールに表示されます。


MutationRecordオブジェクト

ここでは、 class属性の削除によって引き起こされた突然変異を見ることができます。

最後に、作業の完了後にDOMの監視を停止するために、次のことができます。

 //     mutationObserver.disconnect(); 

さまざまなブラウザーでのMutationObserverのサポート


MutationObserver APIは、ブラウザで広くサポートされています。


MutationObserverのサポート

MutationObserverの代替


MutationObserver提供するDOM変更監視メカニズムは、開発者が常に利用できるわけではないことに注意してください。 MutationObserverの登場前、彼らは何を使用していましたか? 以下にいくつかのオプションを示します。


▍調査


DOMの変更を追跡する最も簡単で最も簡単な方法は、ポーリングすることです。 setIntervalメソッドを使用すると、DOMの変更をチェックする関数の定期的な実行をスケジュールできます。 当然、この方法を使用すると、Webアプリケーションのパフォーマンスが大幅に低下します。

utMutationEvents


MutationEvents APIは2000年に導入されました。 このAPIを使用すると、割り当てられたタスクを解決できますが、DOMが変更されるたびにミューテーションイベントが発生し、パフォーマンスの問題が発生します。 現在、 MutationEvents APIは非推奨になり、最近のブラウザーではサポートされなくなります。


MutationEventsのサポート

▍CSSアニメーション


実際、 CSSアニメーションの形式のMutationObserver代替は少し奇妙に見えるかもしれません。 そして、ここにアニメーションがありますか? 一般に、ここでの考え方は、要素がDOMに追加された後に呼び出されるアニメーションを作成することです。 アニメーションが開始されると、animationstartイベントがanimationstartます。 このイベントにハンドラーを割り当てると、新しいアイテムがDOMに追加された正確な時間を確認できます。 この場合、アニメーションの実行時間は非常に短く、ユーザーにはほとんど見えません。

このメソッドを使用するには、最初に親要素が必要です。そのために、新しいノードの追加を観察します。

 <div id="container-element"></div> 

ノードの追加の監視を整理するには、ノードを追加したときに開始されるCSSアニメーションのキーフレームのシーケンスを構成する必要があります。

 @keyframes nodeInserted { from { opacity: 0.99; } to { opacity: 1; } } 

キーフレームを作成した後、アニメーションを監視する必要がある要素に適用する必要があります。 アニメーションの継続時間に注意してください。 非常に小さいため、アニメーションはほとんど見えません。

 #container-element * { animation-duration: 0.001s; animation-name: nodeInserted; } 

ここで、 container-elementすべての子孫ノードにアニメーションを追加しcontainer-element 。 アニメーションが終了すると、対応するイベントが発生します。

ここで、イベントハンドラーの役割を果たすJS関数が必要です。 関数内では、まず、 event.animationNameをチェックして、これが私たちが興味を持っているアニメーションであることを確認する必要があります。

 var insertionListener = function(event) { //   ,     ,    if (event.animationName === "nodeInserted") {   console.log("Node has been inserted: " + event.target); } } 

次に、イベントハンドラーを親要素に追加します。 ブラウザーごとにこれが異なります。

 document.addEventListener("animationstart", insertionListener, false); // standard + firefox document.addEventListener("MSAnimationStart", insertionListener, false); // IE document.addEventListener("webkitAnimationStart", insertionListener, false); // Chrome + Safari 

これが、さまざまなブラウザーでのCSSアニメーションの動作方法です。


さまざまなブラウザーでのCSSアニメーションのサポート

まとめ


MutationObserver APIと、DOMの変更を監視する代替方法を検討しました。 MutationObserverは、これらの選択肢よりも多くの利点があることに注意してください。 一般に、このAPIはDOMで発生する可能性のある変更を報告でき、最適化されており、パッケージに収集された変更に関する情報を提供できると言えます。 さらに、 MutationObserver APIはすべての主要な最新ブラウザーでサポートされており、 MutationEventsに基づいたポリフィルがあります。

この資料の著者は、 MutationObserverSessionStackライブラリの中心であり、Webページで何が起きているかに関するデータの収集を整理することを目的としていることに注目しています。

一連の記事の前の部分:

パート1: JSの仕組み:エンジン、ランタイムメカニズム、コールスタックの概要
パート2: JSの仕組み:V8内部とコードの最適化について
パート3: JSの仕組み:メモリ管理、4種類のメモリリーク、およびそれらとの戦い
パート4: JSの仕組み:イベントループ、非同期、およびasync / awaitを使用してコードを改善する5つの方法
パート5: JSの仕組み:WebSocketとHTTP / 2 + SSE。 何を選ぶ?
パート6: JSの仕組み:WebAssemblyの機能と範囲
パート7: JSの仕組み:Web Workersと5つの使用シナリオ
パート8: JSの仕組み:サービスワーカー
パート9: JSの仕組み:Webプッシュ通知

親愛なる読者! プロジェクトでMutationObserverを使用していますか?

Source: https://habr.com/ru/post/J351256/


All Articles