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

Anunciamos a descontinuação e a remoção planejada dos eventos de mutação e compartilhamos como migrar seu código antes da remoção em julho de 2024.

Mason Freed
Mason Freed

O Chromium desaconselhou oficialmente os eventos de mutação e tem um plano para remover o suporte a partir da versão 127, que vai passar para a versão estável em 23 de julho de 2024. Esta postagem explica por que estamos removendo os eventos de mutação e oferece 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 da seguinte coleção de eventos:

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMCharacterDataModified
  • DOMNodeInsertedIntoDocument
  • DOMNodeRemovedFromDocument
  • (Não tem suporte de nenhum navegador moderno) DOMAttrModified
  • (Não tem suporte de nenhum navegador moderno) DOMAttributeNameChanged
  • (Não tem suporte de nenhum navegador moderno) DOMElementNameChanged

Esses eventos são uma parte muito antiga da especificação do DOM 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

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

  • Elas são detalhadas e são disparadas com muita frequência. Um evento é acionado para cada nó removido.
  • Elas são lentas devido à propagação de eventos e porque impedem muitas otimizações de tempo de execução do UA.
  • Eles costumam causar falhas. Eles foram a origem de muitos travamentos e bugs de segurança em navegadores, porque os listeners de eventos podem mudar todo o DOM em uma operação de DOM em execução.

Por causa dessas falhas, os eventos foram descontinuados da especificação em 2011, e uma API substituta (MutationObserver) foi criada em 2012. A nova API já está implementada e funcional há mais de 10 anos.

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

A compatibilidade com 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 seria: por que não deixá-los lá, já que eles estão "prontos" e apenas retardam as páginas que os usam? A resposta tem duas partes.

Em primeiro lugar, 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 precisa ser levada em conta. À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 impedir que os elementos <iframe> sejam recarregados quando movidos dentro do DOM. No entanto, 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 aceleração dos navegadores. Mesmo com as otimizações que os navegadores têm, que tentam evitar as penalidades de desempenho em páginas que não usam eventos de mutação, as coisas não são perfeitas. Ainda é necessário fazer verificações em muitos lugares para listeners de eventos de mutação. O código ainda precisa ser escrito de forma muito defensiva, já que esses eventos podem mudar o DOM de maneiras surpreendentes.

Como os eventos foram oficialmente descontinuados há mais de 10 anos e a API de substituição está disponível há mais de 10 anos, chegou a hora de 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 é bastante completa. A substituição da 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 única chamada, em vez de exigir várias chamadas para o manipulador de eventos.

Polyfill

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

Cronograma e informações do teste de descontinuação

Os eventos de mutação serão removidos do Chrome 127 para todos os usuários* que vão receber a versão estável em 23 de julho de 2024. Os eventos vão começar a ser removidos dos canais Canary, Dev e Beta antes disso, como um aviso antecipado.

  • Se você precisar de mais tempo (além de julho de 2024) para migrar o código, há um teste de descontinuação que reativa os eventos temporariamente em sites específicos. 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 extras para a migração, se necessário.