Chrome 13, yapılandırılmış klonlama adlı bir algoritma kullanarak bir Web İşleyici'ye/Web İşleyici'den ArrayBuffer
göndermeyi kullanıma sundu. Bu sayede postMessage()
API, yalnızca dize değil, File
, Blob
, ArrayBuffer
ve JSON nesneleri gibi karmaşık türlerde mesajlar da kabul edebiliyordu. Yapılandırılmış klonlama, Firefox'un sonraki sürümlerinde de desteklenir.
Daha hızlı olmak daha iyidir
Yapılandırılmış klonlama harika olsa da yine de bir kopyalama işlemidir. 32 MB'lık bir ArrayBuffer
öğesini bir çalışana aktarmanın yükü yüzlerce milisaniye olabilir.
Tarayıcıların yeni sürümleri, mesaj aktarımı için Transferable Objects adlı büyük bir performans iyileştirmesi içerir.
Aktarılabilir nesnelerde veriler bir bağlamdan diğerine aktarılır. Bu yöntemde kopyalama işlemi yapılmaz. Bu sayede, bir İşleyici'ye veri gönderme performansı büyük ölçüde artar. C/C++ dünyasından geliyorsanız bunu referansla iletim olarak düşünün. Ancak referansla iletilenin aksine, çağıran bağlamdaki "sürüm" yeni bağlama aktarıldıktan sonra kullanılamaz. Örneğin, ana uygulamanızdan çalışana bir ArrayBuffer
aktarırken orijinal ArrayBuffer
temizlenir ve artık kullanılamaz. İçeriği, kelimenin tam anlamıyla Worker bağlamına aktarılır.
Aktarıma uygun öğelerle oynamak için postMessage()
'ın aktarıma uygun nesneleri destekleyen yeni bir sürümü vardır:
worker.postMessage(arrayBuffer, [transferableList]);
window.postMessage(arrayBuffer, targetOrigin, [transferableList]);
İşçi durumunda 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ılabilirler listesinde arrayBuffer
değerini belirtirsiniz.
Karşılaştırma demosu
Aktarıma uygun öğelerin performans kazançlarını görmek için bir demo hazırladım.
Demo, postMessage()
kullanarak bir çalışana 32 MB ArrayBuffer
gönderip geri alır. Tarayıcınız aktarılabilir öğeleri desteklemiyorsa örnek, yapılandırılmış klonlamaya geri döner. Farklı tarayıcılarda ortalama 5 çalıştırma yaptığımda şu sonuçları elde ettim:
MacBook Pro/10.6.8/2, 53 GHz/Intel Core 2 Duo'da yapılandırılmış klonlama kullanılarak en hızlı FF oldu. 32 MB ArrayBuffer
dosyasını bir işleyiciye gönderip ana ileti dizisine geri göndermek ortalama 302 ms sürdü (RTT - gidiş dönüş süresi). Bu, aktarılabilirlerle karşılaştırıldığında aynı testin 6,6 ms sürdüğü anlamına gelir. Bu, performansta büyük bir artış.
Bu tür hızlara sahip olmak, büyük WebGL dokularının/örgelerinin bir işleyici ile ana uygulama arasında sorunsuz bir şekilde aktarılmasına olanak tanır.
Özellik algılama
Bu durumda özellik algılama biraz zordur. Çalışanınıza küçük bir ArrayBuffer
göndermenizi öneririm. Tampon aktarılırsa ancak 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ın pencere ve işleyici için farklı olduğunu gösteren kod snippet'i.
Güncellendi (03.11.2016): Tedarikçi firma ön ekleri kaldırıldı ve kod snippet'leri güncellendi