Anunciamos la baja y la eliminación planificada de los eventos de mutación, y compartimos cómo puedes migrar tu código antes de la eliminación en julio de 2024.
Chromium dio de baja oficialmente los eventos de mutación y tiene un plan para quitar la compatibilidad a partir de la versión 127, que pasará a ser estable el 23 de julio de 2024. En esta publicación, se explica por qué quitaremos los eventos de mutación y se proporciona una ruta para migrar antes de que se quiten del navegador.
¿Qué son los eventos de mutación?
Los eventos de mutación son el nombre de la siguiente colección de eventos:
DOMNodeInserted
DOMNodeRemoved
DOMSubtreeModified
DOMCharacterDataModified
DOMNodeInsertedIntoDocument
DOMNodeRemovedFromDocument
- (No es compatible con ningún navegador moderno)
DOMAttrModified
- (No es compatible con ningún navegador moderno)
DOMAttributeNameChanged
- (No es compatible con ningún navegador moderno)
DOMElementNameChanged
Estos eventos son una parte muy antigua de la especificación del nivel 2 del DOM y dejaron de estar disponibles desde 2011. Se reemplazaron por la interfaz MutationObserver, que es compatible con todos los navegadores modernos desde 2013.
Historial de eventos de mutación
Los eventos de mutación parecían una buena idea hace mucho tiempo, pero resultó que tenían varios defectos fatales:
- Son demasiado detallados y se activan con demasiada frecuencia. Se activa un evento por cada nodo que se quita.
- Son lentas debido a la propagación de eventos y porque impiden muchas optimizaciones del tiempo de ejecución de UA.
- A menudo causan fallas. Han sido la fuente de muchos errores de seguridad y fallas en los navegadores, ya que los objetos de escucha de eventos pueden cambiar todo el DOM debajo de una operación de DOM en ejecución.
Debido a estas fallas, los eventos dejaron de estar disponibles en la especificación en 2011 y se creó una API de reemplazo (MutationObserver
) en 2012. La nueva API se implementó y funciona desde hace más de 10 años.
Por qué se quitarán los eventos de mutación
La compatibilidad con los eventos de mutación varía según el navegador. Algunos eventos, como DOMNodeInsertedIntoDocument
y DOMNodeRemovedFromDocument
, no son compatibles con todos los navegadores. Para los demás eventos, el comportamiento particular varía debido a la falta de una especificación acordada. Sin embargo, una pregunta razonable podría ser: ¿por qué no dejarlos allí, ya que están "terminados" y solo ralentizan las páginas que los usan? La respuesta viene en dos partes.
En primer lugar, estos eventos retrasan la plataforma web. A medida que la Web evoluciona y se agregan nuevas APIs, se debe tener en cuenta la existencia de estas APIs heredadas. A veces, la simple necesidad de admitir estos eventos puede impedir que se propongan nuevas APIs. A modo de ejemplo, existe una solicitud de larga data para evitar que los elementos <iframe>
se vuelvan a cargar cuando se mueven dentro del DOM. Sin embargo, debido en parte a la existencia de eventos de mutación, se consideró que ese esfuerzo era demasiado difícil de lograr y se cerró la solicitud.
Estos eventos siguen dificultando que los navegadores sean más rápidos. Incluso con las optimizaciones que tienen los navegadores, que intentan evitar las penalizaciones de rendimiento en las páginas que no usan eventos de mutación, las cosas no son perfectas. Aún se deben realizar verificaciones en muchos lugares para los objetos de escucha de eventos de mutación. El código aún debe escribirse de forma muy defensiva, ya que estos eventos pueden cambiar el DOM de formas sorprendentes.
Dado que han pasado más de 10 años desde que los eventos dejaron de estar disponibles oficialmente y la API de reemplazo también está disponible desde hace más de 10 años, llegó el momento de quitar los eventos de mutación de los navegadores de una vez por todas.
Cómo realizar la migración
Usa MutationObserver
en su lugar
La documentación de MutationObserver
se encuentra en MDN y es bastante completa. El reemplazo de tu base de código depende de cómo se usen estos eventos, pero, a modo de ejemplo, puedes hacer lo siguiente:
// 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});
Si bien el código MutationObserver
parece más grande que el código original del objeto de escucha de eventos DOMNodeInserted
, ten en cuenta que puede controlar todas las mutaciones que ocurran en todo un árbol con una sola llamada, en lugar de requerir varias llamadas al controlador de eventos.
Polyfill
Hay un polyfill que intenta permitir que el código existente siga funcionando, mientras se alimenta de MutationObserver
. El polyfill se encuentra en GitHub o como un paquete npm.
- https://github.com/mfreed7/mutation-events-polyfill#readme
- https://www.npmjs.com/package/mutation-events
Cronograma y detalles de la prueba de baja
Los eventos de mutación se quitarán de Chrome 127 para todos los usuarios* que pasen a la versión estable el 23 de julio de 2024. Los eventos comenzarán a quitarse de los canales Canary, Dev y Beta antes de esa fecha, como una advertencia anticipada.
- Si necesitas más tiempo (más allá de julio de 2024) para migrar tu código, existe una prueba de baja que vuelve a habilitar los eventos temporalmente en sitios específicos. También hay una política empresarial llamada
MutationEventsEnabled
que funciona de manera similar para los usuarios empresariales. Cualquiera de estas opciones te brinda aproximadamente nueve meses adicionales para realizar la migración, si es necesario.