Zdarzenia mutacji będą usuwane z Chrome

Ogłoszenie wycofania i planowanego usunięcia zdarzeń mutacji oraz informacje o sposobie migracji kodu przed usunięciem w lipcu 2024 roku.

Mason Freed
Mason Freed

Chromium oficjalnie wycofał zdarzenia mutacji i planuje wycofać obsługę wersji 127, która trafi do wersji stabilnej 23 lipca 2024 roku. W tym poście wyjaśniamy, dlaczego usuwamy zdarzenia mutacji, i przedstawiamy ścieżkę migracji, zanim zostaną one usunięte z przeglądarki.

Czym są zdarzenia mutacji?

Zdarzenia mutacji to nazwa tego zbioru 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. Są wycofane w 2011 roku. Zastąpiliśmy je interfejsem MutationObserver, który jest obsługiwany we wszystkich nowoczesnych przeglądarkach od 2013 roku.

Historia zdarzeń mutacji

Dawniej wydawało się nam, że zdarzenia mutacji były dobrym pomysłem, ale okazuje się, że mają kilka poważnych błędów:

  • Są zbyt szczegółowe i zbyt często uruchamiają się. Zdarzenie jest wywoływane dla każdego usuniętego węzła.
  • Działają wolno ze względu na propagację zdarzeń i uniemożliwianie wielu optymalizacji w czasie działania UA.
  • Często powodują 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 powodu tych błędów wycofano te zdarzenia ze specyfikacji w 2011 roku, a w 2012 opracowaliśmy 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. DOMNodeInsertedIntoDocument i DOMNodeRemovedFromDocument, nie są obsługiwane we wszystkich przeglądarkach. W przypadku pozostałych zdarzeń określone zachowanie różni się ze względu na brak uzgodnionej specyfikacji. Można jednak zadać sobie pytanie: dlaczego nie zostawić ich tam, skoro zostały „gotowe”, i spowalniają tylko te strony, które ich używają? Odpowiedź składa się z 2 części.

Po pierwsze, te zdarzenia wstrzymują działanie platformy internetowej. W miarę rozwoju sieci i dodawania nowych interfejsów API trzeba brać pod uwagę istnienie starszych interfejsów API. Czasami sama potrzeba obsługi tych zdarzeń może przeszkodzić w proponowaniu nowych interfejsów API. Na przykład od dawna otrzymaliśmy żądaniezatrzymania ponownego ładowania elementów <iframe> przeniesionych w obrębie DOM. Częściowo jednak ze względu na istnienie zdarzeń mutacji ten wysiłek został uznany za zbyt trudny do osiągnięcia i żądanie zostało zamknięte.

Te zdarzenia nadal wpływają na przyspieszenie działania przeglądarek. Nawet jeśli korzystają one z optymalizacji, która pozwala uniknąć kar na wydajność w przypadku stron, które nie używają zdarzeń mutacji, nie wszystko działa idealnie. Detektory zdarzeń mutacji nadal muszą przeprowadzać weryfikację w wielu miejscach. Kod należy napisać bardzo obronny, ponieważ zdarzenia te mogą zmieniać DOM w zaskakujący sposób.

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

Jak przeprowadzić migrację

Zamiast tego użyj elementu MutationObserver

Dokumentacja projektu MutationObserver znajduje się w MDN i jest dość wyczerpująca. Zastępowanie bazy kodu zależy od sposobu użycia tych zdarzeń. 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ę większy niż oryginalny kod odbiornika zdarzeń DOMNodeInserted, zauważysz, że może obsłużyć wszystkie mutacje, które mają miejsce w całym drzewie w jednym wywołaniu, i nie wymaga wielu wywołań modułu obsługi zdarzeń.

Watolina

Występuje kod polyfill wspierany przez MutationObserver, który próbuje umożliwić dalsze działanie istniejącego kodu. Plik polyfill znajduje się w GitHubie lub jako pakiet npm.

Harmonogram i informacje o okresie próbnym wycofania

Zdarzenia mutacji zostaną usunięte z Chrome 127 w przypadku wszystkich użytkowników*, a 23 lipca 2024 r. zostaną udostępnione w wersji stabilnej. Zaczniemy wcześniej usuwać zdarzenia z kanałów Canary, Dev i beta.

  • Jeśli potrzebujesz więcej czasu (poza lipcem 2024 roku) na przeniesienie kodu, możesz skorzystać z okresu próbnego wycofywania, który tymczasowo ponownie włącza zdarzenia w określonych witrynach. Istnieje też zasada przedsiębiorstwa o nazwie MutationEventsEnabled, która działa w podobny sposób w przypadku użytkowników firmowych. Każda z tych opcji daje w razie potrzeby około 9 miesięcy dodatkowego czasu na migrację.