ogłaszamy wycofanie i planowane usunięcie zdarzeń mutacji oraz informujemy, jak możesz przenieść kod przed usunięciem w lipcu 2024 r.
Chromium oficjalnie wycofało zdarzenia związane z mutacją i planuje zaprzestać ich obsługi od wersji 127, która zostanie wydana 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 żadne nowoczesne przeglądarki)
DOMAttrModified
- (Nieobsługiwane przez żadne nowoczesne przeglądarki)
DOMAttributeNameChanged
- (Nieobsługiwane przez żadne nowoczesne przeglądarki)
DOMElementNameChanged
Te zdarzenia są bardzo starą częścią specyfikacji DOM poziomu 2 i są nieużywane od 2011 roku. Zostały one zastąpione przez interfejs MutationObserver, który jest obsługiwany we wszystkich nowoczesnych przeglądarkach od 2013 r..
Historia zdarzeń mutacji
Zdarzenia mutacji wydawały się dobrym pomysłem, ale okazało się, że mają kilka poważnych wad:
- Są 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. Były one źródłem wielu awarii i błędów związanych z bezpieczeństwem w przeglądarkach, ponieważ detektory zdarzeń mogą zmieniać cały DOM w ramach uruchomionej 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 już od ponad 10 lat wdrażany i działa.
Dlaczego zdarzenia mutacji są usuwane
Obsługa zdarzeń mutacji różni się w zależności od przeglądarki. Niektóre zdarzenia, np. DOMNodeInsertedIntoDocument
i DOMNodeRemovedFromDocument
, 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żesz jednak zadać pytanie: dlaczego nie zostawić ich tam, skoro są „gotowe” i tylko spowalniają strony, które ich używają? Odpowiedź składa się z 2 części.
Po pierwsze, te zdarzenia spowalniają działanie platformy internetowej. 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 wydarzenia nadal utrudniają przyspieszanie 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.
Od oficjalnego wycofania tych zdarzeń minęło już ponad 10 lat, a interfejs API, który je zastępuje, jest dostępny od ponad 10 lat, więc nadszedł czas, aby raz na zawsze usunąć zdarzenia związane z mutacjami z przeglądarek.
Jak przeprowadzić migrację
Użyj w zamian MutationObserver
Dokumentacja MutationObserver
jest dość obszerna i znajduje się na stronie MDN. 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 wszystkie mutacje występujące w całym drzewie w jednym wywołaniu, to nie wymaga wielokrotnego wywoływania metody obsługi zdarzenia.
Wypełnienie
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.
- https://github.com/mfreed7/mutation-events-polyfill#readme
- https://www.npmjs.com/package/mutation-events
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ć Ci 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 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.