Annonce de l'abandon et de la suppression prévue des événements de mutation, et explication de la manière dont vous pouvez migrer votre code avant la suppression en juillet 2024.
Chromium a officiellement abandonné les événements de mutation et prévoit de les supprimer à partir de la version 127, qui sera disponible en version stable le 23 juillet 2024. Cet article explique pourquoi nous supprimons les événements de mutation et fournit un chemin de migration avant qu'ils ne soient supprimés du navigateur.
Que sont les événements de mutation ?
"Événements de mutation" est le nom de la collection d'événements suivante:
DOMNodeInserted
DOMNodeRemoved
DOMSubtreeModified
DOMCharacterDataModified
DOMNodeInsertedIntoDocument
DOMNodeRemovedFromDocument
- (aucun navigateur moderne n'est compatible)
DOMAttrModified
- (aucun navigateur moderne n'est compatible)
DOMAttributeNameChanged
- (Non compatible avec les navigateurs récents)
DOMElementNameChanged
Ces événements font partie d'une très ancienne partie de la spécification DOM de niveau 2 et sont obsolètes depuis 2011. Ils ont été remplacés par l'interface MutationObserver, qui est compatible avec tous les navigateurs modernes depuis 2013.
Historique des événements de mutation
Les événements de mutation semblaient être une bonne idée il y a longtemps, mais ils présentaient plusieurs défauts fatals :
- Ils sont longs et se déclenchent trop souvent. Un événement est déclenché pour chaque nœud supprimé.
- Ils sont lents, en raison de la propagation des événements et parce qu'ils empêchent de nombreuses optimisations d'exécution UA.
- Elles provoquent souvent des plantages. Ils ont été à l'origine de nombreux plantages et bugs de sécurité dans les navigateurs, car les écouteurs d'événements peuvent modifier l'intégralité du DOM sous une opération DOM en cours d'exécution.
En raison de ces défauts, les événements ont été abandonnés de la spécification en 2011 et une API de remplacement (MutationObserver
) a été créée en 2012. La nouvelle API est implémentée et fonctionnelle depuis plus de 10 ans.
Pourquoi les événements de mutation sont-ils supprimés ?
La compatibilité des événements de mutation varie selon les navigateurs. Certains événements, comme DOMNodeInsertedIntoDocument
et DOMNodeRemovedFromDocument
, ne sont pas compatibles avec tous les navigateurs. Pour les autres événements, le comportement varie en raison de l'absence de spécification convenue. Cependant, une question raisonnable pourrait être: pourquoi ne pas les laisser sur place, puisqu'elles sont « terminées » et qu'elles ne ralentissent que les pages qui les utilisent ? La réponse se divise en deux parties.
Tout d'abord, ces événements freinent la plate-forme Web. À mesure que le Web évolue et que de nouvelles API sont ajoutées, l'existence de ces anciennes API doit être prise en compte. Parfois, le simple besoin de prendre en charge ces événements peut empêcher la proposition de nouvelles API. Par exemple, une demande de longue date consiste à empêcher le rechargement des éléments <iframe>
lorsqu'ils sont déplacés dans le DOM. Toutefois, en raison de l'existence d'événements de mutation, cette tâche a été jugée trop difficile à accomplir, et la demande a été clôturée.
Ces événements continuent d'entraver l'accélération des navigateurs. Même avec les optimisations des navigateurs, qui tentent d'éviter les pénalités de performances sur les pages qui n'utilisent pas d'événements de mutation, les choses ne sont pas parfaites. Des vérifications doivent encore être effectuées à de nombreux endroits pour les écouteurs d'événements de mutation. Le code doit toujours être écrit de manière très défensive, car ces événements peuvent modifier le DOM de manière surprenante.
Étant donné que les événements ont été officiellement abandonnés il y a plus de 10 ans et que l'API de remplacement est disponible depuis plus de 10 ans, il est temps de supprimer définitivement les événements de mutation des navigateurs.
Comment procéder ?
Utilisez plutôt MutationObserver
La documentation de MutationObserver
se trouve sur MDN et est assez complète. Le remplacement de votre codebase dépend de la façon dont ces événements sont utilisés, mais voici un exemple :
// 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});
Bien que le code MutationObserver
semble plus volumineux que le code d'écouteur d'événement DOMNodeInserted
d'origine, notez qu'il peut gérer toutes les mutations qui se produisent sur un arbre entier en un seul appel, au lieu de nécessiter plusieurs appels au gestionnaire d'événements.
Polyfill
Un polyfill tente de permettre au code existant de continuer à fonctionner, tout en étant alimenté par MutationObserver
. Le polyfill se trouve sur GitHub ou sous la forme d'un package npm.
- https://github.com/mfreed7/mutation-events-polyfill#readme
- https://www.npmjs.com/package/mutation-events
Calendrier et informations sur l'essai de l'abandon
Les événements de mutation seront supprimés de Chrome 127 pour tous les utilisateurs*. La version stable sera disponible le 23 juillet 2024. Les événements commenceront à être supprimés des canaux Canary, Dev et Bêta avant cette date, à titre d'alerte précoce.
- Si vous avez besoin de plus de temps (après juillet 2024) pour migrer votre code, vous pouvez bénéficier d'un essai de dépréciation qui réactive temporairement les événements sur des sites spécifiés. Il existe également une règle d'entreprise appelée
MutationEventsEnabled
, qui fonctionne de la même manière pour les utilisateurs de la version Enterprise. Ces deux options vous donnent environ neuf mois supplémentaires pour effectuer la migration, si nécessaire.