ระบบจะนำเหตุการณ์การเปลี่ยนแปลงออกจาก Chrome

ประกาศการเลิกใช้งานและแผนการนําเหตุการณ์ Mutation ออก รวมถึงแชร์วิธีย้ายข้อมูลโค้ดก่อนการนําออกในเดือนกรกฎาคม 2024

Mason Freed
Mason Freed

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

ไทม์ไลน์และข้อมูลการทดลองเลิกใช้งาน

ระบบจะนำเหตุการณ์การกลายพันธุ์ออกจาก Chrome 127 สำหรับผู้ใช้ทุกคน* ซึ่งจะเข้าสู่รุ่นเสถียรในวันที่ 23 กรกฎาคม 2024 ระบบจะเริ่มนําเหตุการณ์ออกจากช่องทาง Canary, Dev และเบต้าก่อนวันที่ดังกล่าวเพื่อเป็นการเตือนล่วงหน้า

  • หากต้องการเวลาเพิ่มเติม (หลังจากเดือนกรกฎาคม 2024) เพื่อย้ายข้อมูลโค้ด คุณสามารถใช้ช่วงทดลองการเลิกใช้งาน ซึ่งจะเปิดใช้เหตุการณ์อีกครั้งชั่วคราวในเว็บไซต์ที่ระบุ นอกจากนี้ยังมีนโยบายสำหรับองค์กรชื่อ MutationEventsEnabled ซึ่งทำงานในลักษณะคล้ายกันสำหรับผู้ใช้ระดับองค์กร ตัวเลือกใดตัวเลือกหนึ่งเหล่านี้จะช่วยให้คุณมีเวลาเพิ่มเติมในการย้ายข้อมูลประมาณ 9 เดือน หากจำเป็น