วัตถุที่ถ่ายโอนได้ - เร็วมาก

Chrome 13 ได้เปิดตัวการส่ง ArrayBuffer ไปยัง/จากเว็บเวิร์กเกอร์โดยใช้อัลกอริทึมที่เรียกว่าการโคลนแบบมีโครงสร้าง ซึ่งทำให้ postMessage() API ยอมรับข้อความที่ไม่ใช่แค่สตริงเท่านั้น แต่ยังรับประเภทที่ซับซ้อน เช่น File, Blob, ArrayBuffer และออบเจ็กต์ JSON Firefox เวอร์ชันที่ใหม่กว่ายังรองรับการโคลนแบบมีโครงสร้างด้วย

ยิ่งเร็วยิ่งดี

การโคลนแบบมีโครงสร้างนั้นยอดเยี่ยม แต่ก็ยังเป็นการดำเนินการแบบคัดลอก ค่าใช้จ่ายในการส่ง ArrayBuffer ขนาด 32 MB ไปยังผู้ปฏิบัติงานอาจใช้เวลาหลายร้อยมิลลิวินาที เบราว์เซอร์เวอร์ชันใหม่มีการปรับปรุงประสิทธิภาพอย่างมากสำหรับการส่งข้อความ ซึ่งเรียกว่า Transferable Objects

ออบเจ็กต์ที่โอนได้จะโอนข้อมูลจากบริบทหนึ่งไปยังอีกบริบทหนึ่ง การดำเนินการนี้เป็นแบบไม่คัดลอก ซึ่งจะปรับปรุงประสิทธิภาพการส่งข้อมูลไปยังเวิร์กเกอร์ได้อย่างมาก คุณสามารถมองการเรียกใช้นี้เป็นการพาสโดยรีเฟอเรนซ์ได้หากมาจากโลก C/C++ อย่างไรก็ตาม "เวอร์ชัน" จากบริบทการเรียกใช้จะใช้ไม่ได้อีกต่อไปเมื่อโอนไปยังบริบทใหม่ ซึ่งแตกต่างจากการพาสโดยรีเฟอเรนซ์ ตัวอย่างเช่น เมื่อโอน ArrayBuffer จากแอปหลักไปยังอุปกรณ์ที่ทำงาน ระบบจะล้าง ArrayBuffer เดิมและใช้งานไม่ได้อีกต่อไป ระบบจะโอนเนื้อหาไปยังบริบทของ Worker

หากต้องการเล่นกับรายการที่โอนได้ postMessage() มีเวอร์ชันใหม่ที่รองรับออบเจ็กต์ที่โอนได้ ดังนี้

worker.postMessage(arrayBuffer, [transferableList]);
window.postMessage(arrayBuffer, targetOrigin, [transferableList]);

สำหรับเคสของแรงงาน อาร์กิวเมนต์แรกคือข้อความ ArrayBuffer อาร์กิวเมนต์ที่ 2 คือรายการที่ควรโอน ในตัวอย่างนี้ คุณจะต้องระบุ arrayBuffer ในรายการที่โอนได้

การสาธิตการเปรียบเทียบ

เราได้จัดทำการสาธิตเพื่อให้เห็นถึงประสิทธิภาพที่เพิ่มขึ้นของรายการที่โอนได้

การสาธิตจะส่ง ArrayBuffer ขนาด 32 MB ไปยังผู้ปฏิบัติงานและกลับโดยใช้ postMessage() หากเบราว์เซอร์ไม่รองรับรายการที่โอนได้ ตัวอย่างจะกลับไปใช้การโคลน Structured Data ผลที่ได้จากการทดสอบ 5 ครั้งในเบราว์เซอร์ต่างๆ มีดังนี้

แผนภูมิเปรียบเทียบการโคลนแบบมีโครงสร้างกับออบเจ็กต์ที่โอนได้

ใน MacBook Pro/10.6.8/2.53 GHz/Intel Core 2 Duo นั้น FF ทำงานได้เร็วที่สุดโดยใช้การโคลนแบบมีโครงสร้าง โดยเฉลี่ยแล้ว ระบบใช้เวลา 302 มิลลิวินาทีในการส่ง ArrayBuffer ขนาด 32 MB ไปยังผู้ปฏิบัติงานและโพสต์กลับไปยังชุดข้อความหลัก (RRT - Round Trip Time) เมื่อเปรียบเทียบกับรายการที่โอนได้ การทดสอบเดียวกันนี้ใช้เวลา 6.6 มิลลิวินาที ประสิทธิภาพเพิ่มขึ้นอย่างมาก

ความเร็วระดับนี้ช่วยให้สามารถส่งผ่านพื้นผิว/เมช WebGL ขนาดใหญ่ระหว่าง Worker กับแอปหลักได้อย่างราบรื่น

การตรวจหาฟีเจอร์

การตรวจหาฟีเจอร์นี้ค่อนข้างยาก เราขอแนะนำให้ส่ง ArrayBuffer เล็กๆ ให้กับคนงาน หากมีการโอนบัฟเฟอร์แต่ไม่ได้คัดลอก .byteLength ของบัฟเฟอร์จะเท่ากับ 0

var ab = new ArrayBuffer(1);
worker.postMessage(ab, [ab]);
if (ab.byteLength) {
    alert('Transferables are not supported in your browser!');
} else {
    // Transferables are supported.
}

การรองรับ: ปัจจุบันรองรับ Chrome 17 ขึ้นไป, Firefox, Opera, Safari และ IE10 ขึ้นไป

อัปเดต (13-12-2011): ข้อมูลโค้ดเพื่อแสดงลายเซ็น webkitPostMessage() แตกต่างกันสำหรับ Window และ Worker อัปเดต (03-11-2016): นำคำนำหน้าของผู้ให้บริการออกและอัปเดตข้อมูลโค้ด