Aktarılabilir nesneler: Işık hızında

Chrome 13, yapılandırılmış klonlama adı verilen bir algoritma kullanarak bir web çalışanına/web çalışanından ArrayBuffer gönderme özelliğini kullanıma sundu. Bu da postMessage() API'nin sadece dizelerden oluşan mesajları değil, File, Blob, ArrayBuffer ve JSON nesneleri gibi karmaşık türleri de kabul etmesine olanak tanıyordu. Yapılandırılmış klonlama, Firefox'un sonraki sürümlerinde de desteklenir.

Daha hızlı olmak daha iyidir

Yapılandırılmış klonlama harikadır ancak yine de bir kopyalama işlemidir. Bir Çalışana 32 MB'lık ArrayBuffer iletmenin ek yükü yüzlerce milisaniye olabilir. Tarayıcıların yeni sürümleri, ileti iletimi için Aktarılabilir Nesneler adı verilen büyük bir performans iyileştirmesi sunar.

Aktarılabilir nesnelerle veriler bir bağlamdan diğerine aktarılır. Sıfır kopyadan oluşur ve bir Çalışana veri gönderme performansını büyük ölçüde iyileştirir. C/C++ dünyasındaysanız bunu referans olarak düşünebilirsiniz. Ancak, geçişten farklı olarak, görüşme bağlamındaki "sürüm" yeni bağlama aktarıldıktan sonra kullanılamaz. Örneğin, bir ArrayBuffer öğesini ana uygulamanızdan Çalışana aktarırken orijinal ArrayBuffer temizlenir ve artık kullanılamaz. İçerikleri (sessizce) Çalışan bağlamına aktarılır.

Aktarılabilir öğelerle oynamak için postMessage() ürününün aktarılabilir nesneleri destekleyen yeni bir sürümü var:

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

Çalışan durumu için ilk bağımsız değişken ArrayBuffer mesajıdır. İkinci bağımsız değişken, aktarılması gereken öğelerin listesidir. Bu örnekte, aktarılabilir listede arrayBuffer öğesini belirtirsiniz.

Karşılaştırma demosu

Aktarılabilir öğelerin performans artışlarını görmek için bir demo hazırladım.

Demo, bir çalışana 32 MB boyutunda ArrayBuffer gönderir ve postMessage() ile çalışır. Tarayıcınız aktarılabilir dosyaları desteklemiyorsa örnek, yapılandırılmış klonlama işlemine geri döner. Ortalama 5 farklı tarayıcılarda çalıştığı şöyle bir sonuç elde edilir:

Yapılandırılmış klonlama ve aktarılabilir nesneler karşılaştırma grafiği

MacBook Pro/10.6.8/2.53 GHz/Intel Core 2 Duo'da FF, yapılandırılmış klonlama kullanılarak en hızlı cihazdı. 32 MB boyutundaki ArrayBuffer öğesinin bir çalışana gönderilmesi ve ana ileti dizisinde geri yayınlanması ortalama 302 ms sürdü (RRT - Gidiş Dönüş Süresi). Aktarılabilir öğeler açısından karşılaştırıldığında, aynı test 6,6 ms sürdü. Bu muazzam bir performans artışı.

Bu tür hızlara sahip olmak, devasa WebGL dokularının/örgülerinin bir çalışan ve ana uygulama arasında sorunsuz bir şekilde geçirilmesine olanak tanır.

Özellik algılama

Bu özellikte özellik algılama işlemi biraz karmaşıktır. Çalışanınıza küçük bir ArrayBuffer göndermenizi öneririm. Arabellek aktarılırsa ve kopyalanmazsa .byteLength değeri 0 olur:

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

Destek: Şu anda Chrome 17 ve sonraki sürümler, Firefox, Opera, Safari ve IE10 ve sonraki sürümler

Güncellendi (13.12.2011): webkitPostMessage() imzasını gösterecek kod snippet'i, pencere ve çalışan için farklıdır. Güncellenme tarihi (03.11.2016): Tedarikçi firma önekleri kaldırıldı ve kod snippet'leri güncellendi