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