Zdarzenia mutacji będą usuwane z Chrome

Ogłoszenie wycofania i planowanego usunięcia zdarzeń związanych z mutacjami oraz sposób przeniesienia kodu przed usunięciem w lipcu 2024 r.

Mason Freed
Mason Freed

Chromium oficjalnie wycofało zdarzenia mutacji i planuje usunąć ich obsługę od wersji 127, która zostanie opublikowana w wersji stabilnej 23 lipca 2024 r.. Z tego posta dowiesz się, dlaczego usuwamy zdarzenia mutacji, oraz jak je przenieść, zanim zostaną usunięte z przeglądarki.

Co to są zdarzenia mutacji?

Zdarzenia związane z mutacją to nazwa tej kolekcji zdarzeń:

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMCharacterDataModified
  • DOMNodeInsertedIntoDocument
  • DOMNodeRemovedFromDocument
  • (Nieobsługiwane przez żadną nowoczesną przeglądarkę) DOMAttrModified
  • (Nieobsługiwane przez żadną nowoczesną przeglądarkę) DOMAttributeNameChanged
  • (Nieobsługiwane przez żadną nowoczesną przeglądarkę) DOMElementNameChanged

Te zdarzenia są bardzo starą częścią specyfikacji DOM poziomu 2 i są wycofane od 2011 roku. Zastąpiliśmy je interfejsem MutationObserver, który jest obsługiwany we wszystkich nowoczesnych przeglądarkach od 2013 roku.

Historia zdarzeń związanych z mutacją

Zdarzenia mutacji wydawały się dobrym pomysłem, ale okazało się, że mają kilka krytycznych wad:

  • Są one zbyt długie i wysyłane zbyt często. Dla każdego usuniętego węzła zostanie wywołane zdarzenie.
  • Są one wolne z powodu propagacji zdarzeń i ponieważ uniemożliwiają wiele optymalizacji w czasie wykonywania UA.
  • Często powodują one awarie. Są one źródłem wielu awarii i błędów bezpieczeństwa w przeglądarkach, ponieważ detektory zdarzeń mogą zmieniać cały DOM w ramach trwającej operacji DOM.

Z tego powodu w 2011 r. zostały one wycofane ze specyfikacji, a w 2012 r. opracowano nowy interfejs API (MutationObserver). Nowy interfejs API jest wdrażany i funkcjonujący od ponad 10 lat.

Dlaczego zdarzenia mutacji są usuwane

Obsługa zdarzeń mutacji różni się w zależności od przeglądarki. Niektóre zdarzenia, np. DOMNodeInsertedIntoDocumentDOMNodeRemovedFromDocument, nie są obsługiwane we wszystkich przeglądarkach. W przypadku innych zdarzeń zachowanie może się różnić ze względu na brak uzgodnionych specyfikacji. Można jednak zadać sobie pytanie, dlaczego nie po prostu tak się potraktować, skoro zostały już wykonane i spowalniają tylko strony, które z nich korzystają. Odpowiedź składa się z 2 części.

Po pierwsze, te zdarzenia obciążają platformę internetową. Wraz z rozwojem internetu i dodawaniem nowych interfejsów API należy uwzględnić te starsze interfejsy API. Czasami sama potrzeba obsługi tych zdarzeń może uniemożliwić zaproponowanie nowych interfejsów API. Na przykład od dawna istnieje prośba o zapobieganie ponownemu wczytywaniu elementów <iframe> po ich przenoszeniu w DOM. Jednak ze względu na występowanie zdarzeń mutacji uznano, że to zadanie jest zbyt trudne do wykonania, i zamknięto zgłoszenie.

Te zdarzenia nadal wpływają na przyspieszenie działania przeglądarek. Nawet w przypadku optymalizacji w przeglądarkach, które mają na celu unikanie kar za wydajność na stronach, które nie używają zdarzeń mutacji, nie wszystko jest idealne. W wielu miejscach nadal trzeba wykonywać sprawdzanie w przypadku odbiorników zdarzenia mutacji. Kod nadal musi być napisany w sposób bardzo bezpieczny, ponieważ te zdarzenia mogą zmieniać DOM w nieoczekiwany sposób.

Ponieważ zdarzenia zostały oficjalnie wycofane ponad 10 lat, a zastępczy interfejs API jest dostępny podobnie od ponad 10 lat, przyszedł czas, aby w końcu usunąć zdarzenia mutacji z przeglądarek.

Jak przeprowadzić migrację

Zamiast tego użyj elementu MutationObserver

Dokumentacja MutationObserver jest dostępna na stronie MDN i jest dość obszerna. Zastąpienie kodu źródłowego zależy od sposobu używania tych zdarzeń, ale na przykład:

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

Chociaż kod MutationObserver wydaje się dłuższy niż oryginalny kod DOMNodeInserted, który obsługuje zdarzenia, pamięta, że może on obsługiwać wszystkie mutacje, które występują w całym drzewie, w jednym wywołaniu, zamiast wymagać wielokrotnego wywoływania metody obsługi zdarzeń.

Watolina

Istnieje polyfill, który próbuje umożliwić dotychczasowemu kodowi dalsze działanie, korzystając z funkcji MutationObserver. Rozszerzenie polyfill znajduje się na GitHubie lub jest dostępne jako pakiet npm.

Informacje o harmonogramie i wycofnięciu wersji próbnej

Wydarzenia mutacji zostaną usunięte z Chrome 127 dla wszystkich użytkowników* i wejdą do wersji stabilnej 23 lipca 2024 r. Zdarzenia te zaczniemy usuwać z kanałów Canary, Dev i Beta wcześniej, aby dać użytkownikom wcześniejsze ostrzeżenie.

  • Jeśli potrzebujesz więcej czasu (po lipcu 2024 r.) na przeniesienie kodu, możesz skorzystać z wersji próbnej wycofania, która tymczasowo ponownie włącza te zdarzenia w określonych witrynach. Istnieje też zarządzenie o nazwie MutationEventsEnabled, które działa w podobny sposób w przypadku użytkowników firmowych. Każda z tych opcji daje w razie potrzeby dodatkowe 9 miesięcy na przeprowadzenie migracji.