異動事件將從 Chrome 中移除

宣布變異事件的淘汰和移除計畫,並分享如何在 2024 年 7 月移除前遷移程式碼。

Mason Freed
Mason Freed

Chromium 已正式淘汰突變事件,並計劃從 127 版開始移除支援,該版本將於 2024 年 7 月 23 日推出穩定版。本文將說明我們移除變異事件的原因,並提供在變異事件從瀏覽器移除前,遷移的路徑。

什麼是變異事件?

變異事件是下列事件集合的名稱:

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMCharacterDataModified
  • DOMNodeInsertedIntoDocument
  • DOMNodeRemovedFromDocument
  • (任何新式瀏覽器都不支援) DOMAttrModified
  • (任何新式瀏覽器都不支援) DOMAttributeNameChanged
  • (任何新式瀏覽器都不支援) DOMElementNameChanged

這些事件是 DOM 2 級規格的舊版內容,自 2011 年起已淘汰。這些方法已由 MutationObserver 介面取代,自 2013 年起,所有新版瀏覽器都已支援

變化事件的記錄

變異事件在很久以前聽起來是個好點子,但實際上有幾個致命缺陷

  • 它們太冗長,而且觸發頻率過高。系統會針對每個移除的節點觸發事件。
  • 由於事件傳播,且會阻止許多通用 Analytics 執行階段最佳化,因此這些事件會緩慢
  • 這類程式經常會導致當機。這些事件是瀏覽器中許多當機和安全性錯誤的來源,因為事件接聽器可以變更執行中的 DOM 作業下的整個 DOM。

由於這些缺陷,這些事件在 2011 年已淘汰,並在 2012 年建構了替換 API (MutationObserver)。新版 API 已實作並運作超過 10 年。

為何移除突變事件

不同瀏覽器對突變事件的支援情形不同。部分事件 (例如 DOMNodeInsertedIntoDocumentDOMNodeRemovedFromDocument) 並未在所有瀏覽器中支援。對於其他事件,由於缺乏任何約定的規格,因此特定行為會有所不同。不過,合理的問題可能是:既然這些元素「已完成」,且只會讓使用這些元素的網頁變慢,為何不保留這些元素?答案分為兩部分。

首先,這些事件會拖慢網頁平台的速度。隨著網路的演進,新的 API 也隨之增加,因此必須考量這些舊版 API 的存在。有時,只要需要支援這些事件,就可能無法提出新的 API。舉例來說,長期以來都有人提出要求,希望在 <iframe> 元素在 DOM 中移動時,系統不要重新載入該元素。不過,部分原因是因為變異事件的存在,因此我們認為這項工作難以完成,因此關閉了這項要求。

這些事件會持續影響瀏覽器的速度。即使瀏覽器已進行最佳化,試圖避免未使用突變事件的網頁發生效能懲罰,但仍無法完全避免。但 Mutation Event 事件監聽器仍需要在許多地方進行檢查。由於這些事件可能會以意想不到的方式變更 DOM,因此程式碼仍需以防禦性的方式編寫。

這些事件正式淘汰已超過 10 年,且替換 API 也已推出超過 10 年,因此現在是時候從瀏覽器中徹底移除變異事件。

如何遷移

請改用 MutationObserver

MutationObserver 的說明文件位於 MDN,且相當完整。程式碼基底的替換方式取決於這些事件的使用方式,但舉例來說:

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

雖然 MutationObserver 程式碼看起來比原始 DOMNodeInserted 事件事件監聽器程式碼還要大,但請注意,它可以在單一呼叫中處理整個樹狀結構中發生的所有突變,而不需要多次呼叫事件處理常式。

聚酯纖維

有一個 polyfill 會嘗試讓現有程式碼在 MutationObserver 的支援下繼續運作。polyfill 位於 GitHub 上,或以 npm 套件形式提供。

時程和淘汰前測試資訊

所有使用者* 的 Chrome 127 版將在 2024 年 7 月 23 日推出穩定版,屆時變異事件將從中移除。我們會提早在 Canary、Dev 和 Beta 版中移除這些事件,以便提前發出警告。

  • 如果您需要更多時間 (超過 2024 年 7 月) 來遷移程式碼,可以使用淘汰前測試版,在指定網站上暫時重新啟用事件。此外,還有一個名為 MutationEventsEnabled企業政策,對企業版使用者來說,其運作方式與上述政策類似。無論選擇哪一種方式,您都還會有大約九個月的時間進行遷移作業 (視需要而定)。