ประกาศการเลิกใช้งานและแผนการนําเหตุการณ์ Mutation ออก รวมถึงแชร์วิธีย้ายข้อมูลโค้ดก่อนการนําออกในเดือนกรกฎาคม 2024
Chromium ได้เลิกใช้งานเหตุการณ์การกลายพันธุ์อย่างเป็นทางการแล้ว และมีแผนที่จะนำการสนับสนุนออกตั้งแต่เวอร์ชัน 127 ซึ่งจะเปิดตัวเป็นเวอร์ชันเสถียรในวันที่ 23 กรกฎาคม 2024 โพสต์นี้อธิบายสาเหตุที่เรานํา Mutation Event ออก และแสดงเส้นทางในการย้ายข้อมูลก่อนที่เราจะนําออกจากเบราว์เซอร์
Mutation Event คืออะไร
เหตุการณ์ Mutation คือชื่อของคอลเล็กชันเหตุการณ์ต่อไปนี้
DOMNodeInserted
DOMNodeRemoved
DOMSubtreeModified
DOMCharacterDataModified
DOMNodeInsertedIntoDocument
DOMNodeRemovedFromDocument
- (เบราว์เซอร์สมัยใหม่ไม่รองรับ)
DOMAttrModified
- (เบราว์เซอร์สมัยใหม่ไม่รองรับ)
DOMAttributeNameChanged
- (เบราว์เซอร์สมัยใหม่ไม่รองรับ)
DOMElementNameChanged
เหตุการณ์เหล่านี้เป็นส่วนหนึ่งของข้อกําหนด DOM ระดับ 2 ที่เก่ามาก และเลิกใช้งานแล้วตั้งแต่ปี 2011 อินเทอร์เฟซ MutationObserver เข้ามาแทนที่ ซึ่งเบราว์เซอร์สมัยใหม่ทั้งหมดรองรับมาตั้งแต่ปี 2013
ประวัติเหตุการณ์ Mutation
เหตุการณ์การกลายพันธุ์ฟังดูเป็นแนวคิดที่ดีเมื่อนานมาแล้ว แต่กลับพบว่ามีข้อบกพร่องร้ายแรงหลายประการ ดังนี้
- มีข้อความมากเกินไปและทำงานบ่อยเกินไป ระบบจะเรียกเหตุการณ์สําหรับแต่ละโหนดที่นําออก
- เหตุการณ์เหล่านี้ช้าเนื่องจากมีการนำไปใช้กับเหตุการณ์อื่นๆ และป้องกันไม่ให้เกิดการเพิ่มประสิทธิภาพรันไทม์ของ UA หลายรายการ
- เนื่องจากมักทำให้เกิดข้อขัดข้อง เหตุการณ์เหล่านี้เป็นแหล่งที่มาของการขัดข้องและข้อบกพร่องด้านความปลอดภัยในเบราว์เซอร์ เนื่องจาก Listener ของเหตุการณ์สามารถเปลี่ยน DOM ทั้งหมดที่อยู่ภายใต้การดำเนินการ DOM ที่ทำงานอยู่
ด้วยเหตุนี้ เหตุการณ์จึงถูกเลิกใช้งานจากข้อมูลจำเพาะในปี 2011 และสร้าง API ทดแทน (MutationObserver
) ในปี 2012 API ใหม่นี้ใช้งานได้และใช้งานมาเป็นเวลากว่า 10 ปีแล้ว
เหตุผลที่ระบบนําเหตุการณ์การกลายพันธุ์ออก
การรองรับเหตุการณ์ Mutation จะแตกต่างกันไปตามเบราว์เซอร์ เบราว์เซอร์บางรุ่นไม่รองรับเหตุการณ์บางรายการ เช่น DOMNodeInsertedIntoDocument
และ DOMNodeRemovedFromDocument
สำหรับเหตุการณ์อื่นๆ ลักษณะการทำงานจะแตกต่างกันไปเนื่องจากไม่มีข้อกำหนดที่ตกลงกันไว้ อย่างไรก็ตาม คำถามที่สมเหตุสมผลอาจเป็น "ทำไมไม่ปล่อยไว้อย่างนั้นล่ะ เมื่อมี "เสร็จแล้ว" และทำให้หน้าเว็บที่ใช้ช้าลงเท่านั้น" คำตอบมี 2 ส่วน
ประการแรก เหตุการณ์เหล่านี้กําลังขัดขวางแพลตฟอร์มเว็บ เมื่อเว็บพัฒนาไปเรื่อยๆ และมีการเพิ่ม API ใหม่ๆ เข้ามา เราต้องคำนึงถึง API เดิมเหล่านี้ด้วย บางครั้งความต้องการในการรองรับเหตุการณ์เหล่านี้อาจทำให้เสนอ API ใหม่ไม่ได้ ตัวอย่างเช่น เรามีคำขอมาอย่างยาวนานให้ป้องกันไม่ให้องค์ประกอบ <iframe>
โหลดซ้ำเมื่อมีการย้ายภายใน DOM อย่างไรก็ตาม เนื่องด้วยมีเหตุการณ์การกลายพันธุ์อยู่ด้วย เราจึงถือว่าการดำเนินการดังกล่าวทำได้ยากเกินไปและปิดคำขอดังกล่าว
เหตุการณ์เหล่านี้ยังคงขัดขวางการทําให้เบราว์เซอร์เร็วขึ้น แม้จะมีการเพิ่มประสิทธิภาพที่เบราว์เซอร์มี ซึ่งพยายามหลีกเลี่ยงการลดประสิทธิภาพในหน้าเว็บที่ไม่ได้ใช้เหตุการณ์ Mutation แต่ทุกอย่างก็ยังไม่สมบูรณ์ ยังคงต้องมีการตรวจสอบในหลายตำแหน่งสำหรับผู้ฟังเหตุการณ์ Mutation โค้ดยังคงต้องเขียนอย่างระมัดระวังเนื่องจากเหตุการณ์เหล่านี้อาจเปลี่ยนแปลง DOM ในลักษณะที่คาดไม่ถึง
เนื่องจากเราได้เลิกใช้งานเหตุการณ์อย่างเป็นทางการมานานกว่า 10 ปีแล้ว และ API ที่ใช้แทนก็พร้อมใช้งานมานานกว่า 10 ปีเช่นกัน ตอนนี้ถึงเวลาแล้วที่จะนําเหตุการณ์ Mutation ออกจากเบราว์เซอร์อย่างถาวร
วิธีย้ายข้อมูล
ใช้ 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
โพลีฟีลล์จะอยู่ใน GitHub หรือเป็นแพ็กเกจ npm
- https://github.com/mfreed7/mutation-events-polyfill#readme
- https://www.npmjs.com/package/mutation-events
ไทม์ไลน์และข้อมูลการทดลองเลิกใช้งาน
ระบบจะนำเหตุการณ์การกลายพันธุ์ออกจาก Chrome 127 สำหรับผู้ใช้ทุกคน* ซึ่งจะเข้าสู่รุ่นเสถียรในวันที่ 23 กรกฎาคม 2024 ระบบจะเริ่มนําเหตุการณ์ออกจากช่องทาง Canary, Dev และเบต้าก่อนวันที่ดังกล่าวเพื่อเป็นการเตือนล่วงหน้า
- หากต้องการเวลาเพิ่มเติม (หลังจากเดือนกรกฎาคม 2024) เพื่อย้ายข้อมูลโค้ด คุณสามารถใช้ช่วงทดลองการเลิกใช้งาน ซึ่งจะเปิดใช้เหตุการณ์อีกครั้งชั่วคราวในเว็บไซต์ที่ระบุ นอกจากนี้ยังมีนโยบายสำหรับองค์กรชื่อ
MutationEventsEnabled
ซึ่งทำงานในลักษณะคล้ายกันสำหรับผู้ใช้ระดับองค์กร ตัวเลือกใดตัวเลือกหนึ่งเหล่านี้จะช่วยให้คุณมีเวลาเพิ่มเติมในการย้ายข้อมูลประมาณ 9 เดือน หากจำเป็น