ミューテーション イベントのサポート終了と削除予定、2024 年 7 月の削除前にコードを移行する方法を紹介します。
Chromium ではミューテーション イベントを正式に非推奨とし、バージョン 127 以降のサポートを終了する予定です。バージョン 127 は、2024 年 7 月 23 日に安定版リリースとなります。この投稿では、ミューテーション イベントを削除する理由を説明し、ブラウザから削除される前に移行するためのパスを提供します。
ミューテーション イベントとは
ミューテーション イベントは、次のイベント コレクションの名前です。
DOMNodeInserted
DOMNodeRemoved
DOMSubtreeModified
DOMCharacterDataModified
DOMNodeInsertedIntoDocument
DOMNodeRemovedFromDocument
- (最新のブラウザではサポートされていません)
DOMAttrModified
- (最新のブラウザではサポートされていません)
DOMAttributeNameChanged
- (最新のブラウザではサポートされていません)
DOMElementNameChanged
これらのイベントは DOM レベル 2 仕様からかなり古い部分であり、2011 年に廃止されました。MutationObserver インターフェースに置き換えられました。このインターフェースは 2013 年からすべての最新ブラウザでサポートされています。
ミューテーション イベントの履歴
ミューテーション イベントは、ずっと前からよい考えだと思われましたが、次のようないくつかの致命的な欠陥があることがわかりました。
- 冗長で頻繁に起動されます。ノードが削除されるたびにイベントが発生します。
- イベントの伝播と UA の実行時の最適化の多くが妨げられるため、低速になります。
- 頻繁にクラッシュが発生します。イベント リスナーは実行中の DOM 操作の DOM 全体を変更できるため、これがブラウザのクラッシュやセキュリティ バグを多数発生させる原因となってきました。
こうした欠陥のため、2011 年にイベントは仕様から非推奨となり、2012 年に代替 API(MutationObserver
)が構築されました。この新しい API は、現時点で 10 年以上実装され、機能してきました。
ミューテーション イベントが廃止される理由
ミューテーション イベントのサポートはブラウザによって異なります。一部のイベント(DOMNodeInsertedIntoDocument
や DOMNodeRemovedFromDocument
など)は、一部のブラウザではサポートされていません。その他のイベントについては、合意された仕様がないために具体的な動作が異なります。しかし、妥当な疑問は、「もう終わった」ので、なぜそのまま放置してはならないのか、ということです。それを使うページしか遅くなってしまいますか?その答えは 2 部構成です。
まず、これらのイベントがウェブ プラットフォームを阻害しています。ウェブが進化し、新しい API が追加されるにつれ、こうした従来の API の存在を考慮する必要があります。場合によっては、これらのイベントをサポートする必要があるだけで、新しい API が提案されないこともあります。一例として、<iframe>
要素が DOM 内で移動される際にその要素が再読み込みされないようにするという長期にわたるリクエストがありました。しかし、ミューテーション イベントの存在などにより、その作業は達成が難しすぎると見なされ、リクエストはクローズされました。
こうしたイベントは、ブラウザの高速化の妨げとなっています。ミューテーション イベントを使用しないページでのパフォーマンス低下を回避するためにブラウザが最適化を行っても、状況は完全ではありません。ミューテーション イベント リスナーに対しては、引き続きさまざまな場所でチェックを行う必要があります。これらのイベントによって 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
を利用しながら既存のコードを引き続き使用できるようにするポリフィルがあります。polyfill は GitHub 上または npm パッケージとして提供されています。
- https://github.com/mfreed7/mutation-events-polyfill#readme
- https://www.npmjs.com/package/mutation-events
タイムラインとデプリケーション トライアルに関する情報
すべてのユーザーの Chrome 127 からミューテーション イベントが削除され*、2024 年 7 月 23 日に Stable リリースに移行します。イベントは、早期警告として、それよりも前に Canary、Dev、Beta の各チャンネルから削除されます。
- コードの移行に時間が必要な場合は(2024 年 7 月以降)、デプリケーション トライアルを利用すると、指定したサイトでイベントを一時的に再度有効にできます。
MutationEventsEnabled
というエンタープライズ ポリシーもあります。これは、企業ユーザーに対して同様に機能します。どちらのオプションでも、必要に応じて移行に約 9 か月の猶予が与えられます。