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): นำคำนำหน้าของผู้ให้บริการออกและอัปเดตข้อมูลโค้ด