Objek yang dapat ditransfer - Secepat kilat

Chrome 13 memperkenalkan pengiriman ArrayBuffer ke/dari Pekerja Web menggunakan algoritma yang disebut cloning terstruktur. Hal ini memungkinkan postMessage() API menerima pesan yang tidak hanya berupa string, tetapi juga jenis kompleks seperti objek File, Blob, ArrayBuffer, dan JSON. Cloning terstruktur juga didukung di Firefox versi terbaru.

Lebih cepat lebih baik

Cloning terstruktur memang bagus, tetapi masih merupakan operasi penyalinan. Overhead yang meneruskan ArrayBuffer 32 MB ke Pekerja dapat mencapai ratusan milidetik. Browser versi baru berisi peningkatan performa yang sangat besar untuk penerusan pesan, yang disebut Transferable Objects.

Dengan objek yang dapat ditransfer, data akan ditransfer dari satu konteks ke konteks lainnya. Ini adalah zero-copy, yang sangat meningkatkan performa pengiriman data ke Pekerja. Anggap saja ini sebagai referensi {i>pass-by-reference <i} jika Anda berasal dari dunia C/C++. Namun, tidak seperti referensi yang lewat, 'versi' dari konteks panggilan tidak lagi tersedia setelah ditransfer ke konteks baru. Misalnya, saat mentransfer ArrayBuffer dari aplikasi utama ke Worker, ArrayBuffer asli akan dihapus dan tidak dapat digunakan lagi. Kontennya (secara harfiah) ditransfer ke konteks Pekerja.

Untuk bermain dengan objek yang dapat ditransfer, ada versi baru postMessage() yang mendukung objek yang dapat ditransfer:

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

Untuk kasus pekerja, argumen pertama adalah pesan ArrayBuffer. Argumen kedua adalah daftar item yang harus ditransfer. Dalam contoh ini, Anda akan menentukan arrayBuffer dalam daftar yang dapat ditransfer.

Demo benchmark

Untuk melihat peningkatan performa dari perangkat yang dapat ditransfer, saya telah menyusun demo.

Demo mengirimkan ArrayBuffer 32 MB ke pekerja dan kembali menggunakan postMessage(). Jika browser Anda tidak mendukung transfer, contoh akan beralih kembali ke cloning terstruktur. Rata-rata 5 run di browser yang berbeda, ini yang saya dapatkan:

Diagram perbandingan kloning terstruktur vs objek yang dapat ditransfer

Pada MacBook Pro/10.6.8/2.53 GHz/Intel Core 2 Duo, FF adalah yang tercepat menggunakan kloning terstruktur. Rata-rata, perlu waktu 302 md untuk mengirim ArrayBuffer 32 MB ke pekerja dan mempostingnya kembali ke thread utama (RRT - Waktu Round Trip). Dibandingkan dengan perangkat yang dapat ditransfer, pengujian yang sama memerlukan waktu 6,6 md. Itu peningkatan kinerja yang sangat besar!

Memiliki kecepatan semacam ini memungkinkan tekstur/mesh WebGL yang sangat besar dapat diteruskan dengan mulus antara Pekerja dan aplikasi utama.

Mendeteksi fitur

Deteksi fitur sedikit rumit dengan fitur ini. Rekomendasi saya adalah mengirim ArrayBuffer kecil ke pekerja Anda. Jika buffer ditransfer dan tidak disalin, .byteLength-nya akan menjadi 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.
}

Dukungan: Saat ini Chrome 17+, Firefox, Opera, Safari, dan IE10+

Diperbarui (13-12-2011): Cuplikan kode untuk menampilkan tanda tangan webkitPostMessage() berbeda untuk jendela dan pekerja. Diperbarui (03-11-2016): Menghapus awalan vendor dan cuplikan kode yang diperbarui