Les événements de mutation seront supprimés de Chrome

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.

Mason Freed
Mason Freed

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 ?

Les événements de mutation désignent 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
  • (aucun navigateur moderne n'est compatible) 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.
  • Ils 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 prise en charge des événements de mutation varie d'un navigateur à l'autre. Certains événements, comme DOMNodeInsertedIntoDocument et DOMNodeRemovedFromDocument, ne sont pas compatibles avec tous les navigateurs. Pour les autres événements, le comportement particulier varie en raison de l'absence de spécification convenue. Toutefois, une question raisonnable pourrait être: pourquoi ne pas les laisser là, puisqu'ils sont "terminés" et qu'ils ne ralentissent que les pages qui les utilisent ? La réponse se compose de 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, la simple nécessité 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 toujours ê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.

Depuis plus de 10 ans que les événements sont officiellement obsolètes 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.

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 manière similaire pour les utilisateurs professionnels. Ces deux options vous donnent environ neuf mois supplémentaires pour effectuer la migration, si nécessaire.