ミューテーション イベントのサポート終了と今後の削除について発表し、2024 年 7 月の削除までにコードを移行する方法を共有します。
Chromium では、ミューテーション イベントが正式に非推奨になりました。2024 年 7 月 23 日に Stable 版リリースとなるバージョン 127 以降はサポートを終了する予定です。この投稿では、ミューテーション イベントを削除する理由を説明し、ブラウザから削除される前に移行する方法を紹介します。
ミューテーション イベントとは
ミューテーション イベントは、次のイベントのコレクションの名前です。
DOMNodeInserted
DOMNodeRemoved
DOMSubtreeModified
DOMCharacterDataModified
DOMNodeInsertedIntoDocument
DOMNodeRemovedFromDocument
- (最新のブラウザではサポートされていません)
DOMAttrModified
- (最新のブラウザではサポートされていません)
DOMAttributeNameChanged
- (最新のブラウザではサポートされていません)
DOMElementNameChanged
これらのイベントは DOM レベル 2 仕様のかなり古い部分であり、2011 年にサポートを終了しました。代わりに MutationObserver インターフェースが導入されました。MutationObserver インターフェースは、2013 年以降、すべての最新ブラウザでサポートされています。
ミューテーション イベントの履歴
以前、ミューテーション イベントは良い考えに思えましたが、いくつかの致命的な欠陥があることが判明しました。
- 冗長で、頻繁に起動されます。ノードが削除されるたびにイベントが発生します。
- イベントの伝播と UA ランタイムの最適化の妨げになるので、低速です。
- 頻繁にクラッシュが発生します。イベント リスナーは実行中の DOM 操作の背後にある DOM 全体を変更する可能性があるため、これらはブラウザでの多くのクラッシュやセキュリティ バグの原因となっています。
これらの欠陥により、このイベントは 2011 年に仕様のサポートが終了し、2012 年に代替 API(MutationObserver
)が作成されました。新しい API は、実装されてから 10 年以上が経過し、機能しています。
ミューテーション イベントが削除される理由
ミューテーション イベントのサポートはブラウザによって異なります。DOMNodeInsertedIntoDocument
や DOMNodeRemovedFromDocument
などの一部のイベントは、一部のブラウザでサポートされていません。その他のイベントについては、合意された仕様が存在しないため、特定の動作が異なります。しかし、妥当な疑問はこうです。「終了」しただけで、それを使用するページしか遅くなってしまうので、そのままにしてはいけないのでしょうか?その答えは 2 つあります
第一に、これらのイベントがウェブ プラットフォームの足かせになっています。ウェブが進化し、新しい API が追加されるにつれて、こうした従来の API の存在を考慮する必要があります。これらのイベントをサポートするだけでは、新しい API が提案されない場合があります。一例として、<iframe>
要素が DOM 内で移動されたときに再読み込みされないようにするための長期にわたるリクエストがありました。しかし、突然変異イベントが存在することもあり、この取り組みは実現が難しすぎると判断され、リクエストはクローズされました。
これらのイベントは、引き続きブラウザの高速化の妨げとなります。ミューテーション イベントを使用しないページのパフォーマンス低下を回避するためにブラウザが最適化を実施していても、事態は完全ではありません。Mutation Event リスナーのチェックは、依然としてさまざまな場所で行う必要があります。これらのイベントによって驚くべき方法で DOM が変更される可能性があるため、コードは十分に防御的に記述する必要があります。
イベントが正式に非推奨になってから 10 年以上が経過し、代替 API も同様に 10 年以上前から利用可能になっているため、最終的にブラウザから突然変異イベントを削除するときが来ています。
移行方法
代わりに MutationObserver
を使用してください
MutationObserver
のドキュメントは MDN にあり、かなり完全です。コードベースの置き換えは、これらのイベントがどのように使用されているかによって異なりますが、たとえば次のようになります。
// Old mutation event usage:
target.addEventListener('DOMNodeInserted',event => doSomething(event.target));
// Replacement mutation observer code:
const observer = new MutationObserver(mutationList =>
mutationList.filter(m => m.type === 'childList').forEach(m => {
m.addedNodes.forEach(doSomething);
}));
observer.observe(target,{childList: true, subtree: true});
MutationObserver
コードは元の DOMNodeInserted
イベント リスナー コードよりも大きく見えますが、イベント ハンドラを複数回呼び出すのではなく、ツリー全体で発生するすべてのミューテーションを 1 回の呼び出しで処理できます。
ポリフィル
MutationObserver
を利用しながら、既存のコードを機能させようとするポリフィルがあります。ポリフィルは、GitHub または npm パッケージとして入手できます。
- https://github.com/mfreed7/mutation-events-polyfill#readme
- https://www.npmjs.com/package/mutation-events
タイムラインと非推奨トライアルに関する情報
すべてのユーザーの Chrome 127* から変更イベントが削除されます*。Stable 版リリースは 2024 年 7 月 23 日にリリースされます。早期警告として、このイベントに先立ち、Canary、Dev、Beta の各チャンネルからイベントの削除が開始されます。
- コードの移行にさらに時間が必要な場合(2024 年 7 月以降)は、非推奨トライアルを利用して、指定したサイトでイベントを一時的に再度有効にできます。企業ユーザーのために同様に機能する
MutationEventsEnabled
というエンタープライズ ポリシーもあります。どちらの方法でも、必要に応じて移行に約 9 か月の余裕があります。