異動事件將從 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 版、開發人員版和 Beta 版中移除,提前發出警示。

  • 如果需要更多時間 (2024 年 7 月後) 遷移程式碼,我們提供淘汰試用期,可在指定網站上暫時重新啟用事件。另外還有一項名為 MutationEventsEnabledEnterprise 政策,對企業使用者的運作方式很類似。上述任一方案都能提供大約九個月的時間,讓你視需要進行遷移。