Annuncio del ritiro e della rimozione pianificata degli eventi di mutazione e condivisione delle modalità di migrazione del codice prima della rimozione a luglio 2024.
Chromium ha ufficialmente ritirato gli eventi di mutazione e prevede di rimuoverne il supporto a partire dalla versione 127, che verrà rilasciata in versione stabile il 23 luglio 2024. Questo post spiega perché stiamo rimuovendo gli eventi di mutazione e fornisce un percorso per la migrazione prima che vengano rimossi dal browser.
Che cosa sono gli eventi di mutazione?
Eventi di mutazione è il nome della seguente raccolta di eventi:
DOMNodeInserted
DOMNodeRemoved
DOMSubtreeModified
DOMCharacterDataModified
DOMNodeInsertedIntoDocument
DOMNodeRemovedFromDocument
- (non supportato da nessun browser moderno)
DOMAttrModified
- (non supportato da nessun browser moderno)
DOMAttributeNameChanged
- (non supportato da nessun browser moderno)
DOMElementNameChanged
Questi eventi fanno parte di una parte molto vecchia della specifica DOM di livello 2 e sono stati deprecati dal 2011. Sono stati sostituiti dall'interfaccia MutationObserver, supportata in tutti i browser moderni dal 2013.
Cronologia degli eventi di mutazione
Gli eventi di mutazione sembravano una buona idea molto tempo fa, ma si sono rivelati avere diversi difetti fatali:
- Sono troppo verbosi e vengono eseguiti troppo spesso. Viene attivato un evento per ogni nodo rimosso.
- Sono lenti a causa della propagazione degli eventi e perché impediscono molte ottimizzazioni di UA in fase di esecuzione.
- Spesso causano arresti anomali. Sono stati la causa di molti arresti anomali e bug di sicurezza nei browser, perché gli ascoltatori di eventi possono modificare l'intero DOM sotto un'operazione DOM in esecuzione.
A causa di questi difetti, gli eventi sono stati ritirtati dalle specifiche nel 2011 e nel 2012 è stata creata un'API sostitutiva (MutationObserver
). La nuova API è stata implementata e funzionante da oltre 10 anni.
Perché gli eventi di mutazione vengono rimossi
Il supporto degli eventi di mutazione varia in base al browser. Alcuni eventi, ad esempio DOMNodeInsertedIntoDocument
e DOMNodeRemovedFromDocument
, non sono supportati in tutti i browser. Per gli altri eventi, il comportamento specifico varia a causa della mancanza di una specifica concordata. Tuttavia, una domanda ragionevole potrebbe essere: perché non lasciarli lì, dato che sono "completati" e rallentano solo le pagine che li utilizzano? La risposta è composta da due parti.
Innanzitutto, questi eventi stanno frenando la piattaforma web. Con l'evoluzione del web e l'aggiunta di nuove API, è necessario tenere conto dell'esistenza di queste API precedenti. A volte, la sola necessità di supportare questi eventi può impedire la proposta di nuove API. Ad esempio, esiste una richiesta di lunga data per impedire il ricaricamento degli elementi <iframe>
quando vengono spostati all'interno del DOM. Tuttavia, in parte a causa dell'esistenza di eventi di mutazione, questo sforzo è stato ritenuto troppo difficile da realizzare e la richiesta è stata chiusa.
Questi eventi continuano a ostacolare l'aumento della velocità dei browser. Anche con le ottimizzazioni dei browser, che tentano di evitare le penalizzazioni del rendimento nelle pagine che non utilizzano gli eventi di mutazione, le cose non sono perfette. Per gli ascoltatori di eventi di mutazione devono ancora essere eseguiti controlli in molti punti. Il codice deve comunque essere scritto in modo molto sicuro, poiché questi eventi possono modificare il DOM in modi sorprendenti.
Poiché sono trascorsi più di 10 anni dal ritiro ufficiale degli eventi e l'API sostitutiva è disponibile da oltre 10 anni, è arrivato il momento di rimuovere definitivamente gli eventi di mutazione dai browser.
Come eseguire la migrazione
Utilizza MutationObserver
La documentazione di MutationObserver
è disponibile su MDN ed è abbastanza completa. La sostituzione della base di codice dipende dal modo in cui vengono utilizzati questi eventi, ma ad esempio:
// 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});
Sebbene il codice MutationObserver
sia più grande del codice dell'ascoltatore di eventi DOMNodeInserted
originale, tieni presente che può gestire tutte le mutazioni che si verificano in un intero albero in una sola chiamata, anziché richiedere più chiamate al gestore degli eventi.
Polyfill
Esiste un polyfill che tenta di consentire al codice esistente di continuare a funzionare, pur essendo basato su MutationObserver
. Il polyfill si trova su GitHub o come pacchetto npm.
- https://github.com/mfreed7/mutation-events-polyfill#readme
- https://www.npmjs.com/package/mutation-events
Informazioni sulle tempistiche e sulla prova del ritiro
Gli eventi di mutazione verranno rimossi da Chrome 127 per tutti gli utenti* che passeranno alla versione stabile il 23 luglio 2024. Gli eventi inizieranno a essere rimossi dai canali Canary, Dev e Beta prima di questa data, come avviso in anteprima.
- Se hai bisogno di più tempo (oltre a luglio 2024) per eseguire la migrazione del codice, è disponibile una prova di ritiro che riattiva temporaneamente gli eventi su siti specifici. Esiste anche un criterio aziendale denominato
MutationEventsEnabled
che funziona in modo simile per gli utenti aziendali. Entrambe le opzioni offrono circa nove mesi di tempo extra per la migrazione, se necessario.