Os eventos de mutação serão removidos do Chrome

Anunciamos a descontinuação e a remoção planejada de eventos de mutação, além de compartilhar como migrar seu código antes da remoção, em julho de 2024.

Mason Freed
Mason Freed

O Chromium descontinuou oficialmente os eventos de mutação e tem um plano para remover o suporte a partir da versão 127, que vai para a versão estável em 23 de julho de 2024. Esta postagem explica por que estamos removendo eventos de mutação e fornece um caminho para a migração antes que eles sejam removidos do navegador.

O que são eventos de mutação?

"Eventos de mutação" é o nome deste conjunto de eventos:

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMCharacterDataModified
  • DOMNodeInsertedIntoDocument
  • DOMNodeRemovedFromDocument
  • Esse recurso não é compatível com navegadores mais recentes. DOMAttrModified
  • Esse recurso não é compatível com navegadores mais recentes. DOMAttributeNameChanged
  • Esse recurso não é compatível com navegadores mais recentes. DOMElementNameChanged

Esses eventos são uma parte muito antiga da especificação DOM de nível 2 e foram descontinuados desde 2011. Eles foram substituídos pela interface MutationObserver, que tem suporte em todos os navegadores modernos desde 2013.

Histórico de eventos de mutação

Eventos de mutação pareciam uma boa ideia há muito tempo, mas acabaram tendo várias falhas fatais:

  • Elas são prolixas e disparam com frequência. Um evento é disparado para cada nó removido.
  • Elas são lentas devido à propagação de eventos e porque impedem muitas otimizações no tempo de execução do UA.
  • Elas costumam causar falhas. Elas têm sido a fonte de muitas falhas e bugs de segurança em navegadores, porque os listeners de eventos podem alterar todo o DOM em uma operação DOM em execução.

Devido a essas falhas, os eventos foram descontinuados na especificação em 2011, e uma API de substituição (MutationObserver) foi criada em 2012. A nova API já foi implementada e está em funcionamento há mais de 10 anos.

Por que eventos de mutação estão sendo removidos

O suporte para eventos de mutação varia de acordo com o navegador. Alguns eventos, como DOMNodeInsertedIntoDocument e DOMNodeRemovedFromDocument, não são compatíveis com todos os navegadores. Para os outros eventos, o comportamento varia devido à ausência de uma especificação acordada. No entanto, uma pergunta razoável pode ser: por que não apenas deixá-los lá, já que estão "concluídos" e eles apenas retardam as páginas que os utilizam? A resposta tem duas partes.

Em primeiro lugar, esses eventos estão impedindo a plataforma Web. À medida que a Web evolui e novas APIs são adicionadas, é preciso levar em consideração a existência dessas APIs legadas. Às vezes, apenas a necessidade de oferecer suporte a esses eventos pode impedir que novas APIs sejam propostas. Por exemplo, há uma solicitação há muito tempo para evitar que elementos <iframe> sejam atualizados quando são movidos dentro do DOM. No entanto, em parte devido à existência de eventos de mutação, esse esforço foi considerado muito difícil de ser alcançado, e a solicitação foi encerrada.

Esses eventos continuam atrapalhando a velocidade dos navegadores. Mesmo com as otimizações dos navegadores, que tentam evitar as penalidades de desempenho em páginas que não usam eventos de mutação, as coisas não estão perfeitas. As verificações ainda precisam ser feitas em muitos lugares para listeners de eventos de mutação. O código ainda precisa ser escrito de maneira muito defensiva, pois esses eventos podem alterar o DOM de maneiras surpreendentes.

Como os eventos foram oficialmente descontinuados há mais de 10 anos, e a API substituta está disponível há mais de 10 anos, chegou a hora de finalmente remover os eventos de mutação dos navegadores de uma vez por todas.

Como migrar

Use MutationObserver.

A documentação de MutationObserver está localizada no MDN e está bastante completa. A substituição da sua base de código depende de como esses eventos estão sendo usados, mas como exemplo:

// 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});  

Embora o código MutationObserver pareça maior que o código do listener de eventos DOMNodeInserted original, ele pode processar todas as mutações que ocorrem em uma árvore inteira em uma chamada, em vez de exigir várias chamadas para o manipulador de eventos.

Plástico poligonal

Há um polyfill que tenta permitir que o código existente continue funcionando, sendo alimentado por MutationObserver. O polyfill está localizado no GitHub ou como um pacote npm.

Informações sobre o cronograma e os testes de descontinuação

Os eventos de mutação vão ser removidos do Chrome 127 para todos os usuários*. A versão estável vai ser lançada em 23 de julho de 2024. Como um aviso antecipado, os eventos serão removidos dos canais Canary, Dev e Beta antes disso.

  • Se você precisar de mais tempo (após julho de 2024) para migrar seu código, há um teste de descontinuação, que reativa os eventos temporariamente em sites especificados. Há também uma política corporativa chamada MutationEventsEnabled, que funciona de maneira semelhante para usuários corporativos. Qualquer uma dessas opções oferece cerca de nove meses de tempo extra para a migração, se necessário.