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

Anunciamos a descontinuação e a remoção planejada de eventos de mutação e compartilhamos como você pode 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 chegará à 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 do seguinte conjunto de eventos:

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMCharacterDataModified
  • DOMNodeInsertedIntoDocument
  • DOMNodeRemovedFromDocument
  • (Não é compatível com navegadores mais recentes) DOMAttrModified
  • (Não é compatível com navegadores mais recentes) DOMAttributeNameChanged
  • (Não é compatível com navegadores mais recentes) DOMElementNameChanged

Esses eventos são uma parte muito antiga da especificação do DOM nível 2 e foram descontinuados desde 2011. Elas foram substituídas pela interface MutationObserver, compatível com 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:

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

Devido a essas falhas, os eventos foram descontinuados nas especificações em 2011, e uma API substituta (MutationObserver) foi criada em 2012. A nova API já está implementada e funcionando 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 específico varia devido à falta 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 só deixam as páginas com esse conteúdo mais lento? A resposta vem em duas partes.

Primeiro, esses eventos estão impedindo a plataforma da Web. À medida que a Web evolui e novas APIs são adicionadas, a existência dessas APIs legadas deve ser levada em consideração. Às vezes, apenas a necessidade de oferecer suporte a esses eventos pode impedir que novas APIs sejam propostas. Por exemplo, há uma solicitação antiga para evitar que elementos <iframe> sejam recarregados quando forem movidos dentro do DOM. No entanto, parcialmente devido à existência de eventos de mutação, esse esforço foi considerado muito difícil de realizar, e a solicitação foi encerrada.

Esses eventos continuam atrapalhando a velocidade dos navegadores. Mesmo com as otimizações dos navegadores, que tentam evitar penalidades de desempenho em páginas que não usam eventos de mutação, as coisas não sã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, já que esses eventos podem alterar o DOM de maneiras surpreendentes.

Já que faz mais de 10 anos desde que os eventos foram oficialmente descontinuados e a API de substituição 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 para 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 original do listener de eventos DOMNodeInserted, observe que ele pode lidar com todas as mutações que ocorrem em uma árvore inteira em uma chamada, em vez de exigir várias chamadas ao manipulador de eventos.

Polyfill

Existe um polyfill que tenta permitir que um código existente continue funcionando com a tecnologia MutationObserver. O polyfill está localizado no GitHub ou como um pacote npm.

Informações sobre o cronograma e o teste de descontinuação

Os eventos de mutação vão ser removidos do Chrome 127 para todos os usuários* que vão passar para a versão estável 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 (além de julho de 2024) para migrar seu código, use um teste de descontinuação que reativa os eventos temporariamente em sites específicos. Também existe 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 fazer a migração, se necessário.