web-dev-qa-db-ja.com

MutationObserverコールバックはいつ発生しますか?

MutationObserversコールバックは、DOMの変更後に呼び出される可能性があることを知っています。しかし、問題は、これらのコールバックのタイミングは何ですか?コールバックはブラウザのイベントキューに入りますか?もしそうなら、彼らはいつキューに入るのですか?

コールバックは次のとおりです。

  • dOMミューテーションが発生した直後に呼び出され、
  • dOMを操作する関数が終了するとすぐに呼び出されます。
  • コールスタックが空になるとすぐに呼び出され、
  • dOMミューテーションが発生した直後にキューに入れられ、
  • dOMを操作する関数が終了するとすぐにキューに入れられるか、または
  • 他の時に?

たとえば、次のコードが実行された場合( ここで定義されたsetZeroTimeout ):

var target = document.body;

new MutationObserver(function(mutations) {
  console.log('MutationObserver');
}).observe(target, {
  attributes: true,
  childList: true,
  characterData: true
});


// Post message
setZeroTimeout(function () { console.log('message event'); });
// DOM mutation
target.setAttribute("data-test", "value");

「MutationObserver」は「メッセージイベント」の前または後に印刷する必要がありますか?それとも実装定義ですか?

Chromium 26の「メッセージイベント」の前に「MutationObserver」が表示されますが、DOMミューテーションはメッセージの投稿後に発生します。おそらくこれは、MutationObserverコールバックがイベントキューを使用していないnotであることを示しています。

HTML仕様、DOM仕様、またはブラウザ実装ドキュメントをグーグルで検索しましたが、この動作に関連するものは見つかりませんでした。

MutationObserversコールバックのタイミングに関する説明やドキュメントはありますか?

34
FelisCatus

WHATWGから更新されたDOM仕様 に従って、2年後に自分の質問に答えるつもりです。

仕様に示されているように:

ミューテーションオブザーバー複合マイクロタスクをキューに入れるには、次の手順を実行します。

  1. ミューテーションオブザーバー複合マイクロタスクキューフラグが設定されている場合は、これらの手順を終了します。
  2. ミューテーションオブザーバー複合マイクロタスクキューフラグを設定します。
  3. 複合マイクロタスクをキューに入れて、ミューテーションオブザーバーに通知します。

「複合マイクロタスクのキューイング」は HTML仕様のセクション マイクロタスクキューモデルの説明にリンクしています。

したがって、MutationObserverコールバックはマイクロタスクとして発生すると結論付けることができます。これは、 上記の@Scott Milesの回答 で提案されているように、タスクキュータスクよりも実際に早く発生します。

イベントループと処理モデルをさらに理解するには、HTML仕様の イベントループセクション が最適です。

個人的には、MutationObserversが標準の一部であり、十分に文書化された一貫性のあるタイミングモデルを備えていることを嬉しく思います。 MutationObservers 最近のほとんどのブラウザでサポートされています を使用すると、現在、本番環境での使用に適していると思います。

17
FelisCatus

MutationObserverは非同期で起動されますが、「すぐに」起動されます。つまり、レイアウト、ペイント、トリガーされたイベントなど、キュー内の他のものよりも先に起動されます。

これにより、同期の喪失が改善されます。これは、オブザーバーが反応する前に、画面の点滅やその他の悪いことが起こることを心配する必要がないためです。

開発者向けのメモでは、「マイクロタスクの終了」タイミングモデルについて説明しています。私はこれが十分に文書化されていないことに同意します。

20
Scott Miles