عناصر قابلة للنقل - بسرعة فائقة

قدّم Chrome 13 ميزة إرسال ArrayBuffer إلى/من "عامل ويب" باستخدام خوارزمية تسمى الاستنساخ المنظَّم. وقد سمح ذلك لواجهة برمجة التطبيقات postMessage() بقبول الرسائل التي لم تكن سلاسل فحسب، بل أصبحت أنواعًا معقدة، مثل عناصر File وBlob وArrayBuffer وJSON. يتوفر الاستنساخ الهيكلي أيضًا في الإصدارات الأحدث من فايرفوكس.

الأسرع أفضل

الاستنساخ المنظم أمر رائع، ولكنه لا يزال عملية نسخ. يمكن أن تصل مدة تمرير ArrayBuffer بحجم 32 ميغابايت إلى العامل إلى مئات المللي ثانية. تحتوي الإصدارات الجديدة من المتصفحات على تحسُّن كبير في أداء تمرير الرسائل، يُطلق عليها العناصر القابلة للتحويل.

باستخدام العناصر القابلة للنقل، يتم نقل البيانات من سياق إلى آخر. إنها نسخة صفرية، مما يحسّن بشكل كبير من أداء إرسال البيانات إلى العامل. فكر في الأمر على أنه إشارة مرجعية إذا كنت من عالم C/C++. على عكس الإشارة المرجعية، لا تكون "النسخة" من سياق الاستدعاء متاحة بعد نقلها إلى السياق الجديد. على سبيل المثال، عند نقل ArrayBuffer من تطبيقك الرئيسي إلى تطبيق Worker، يتم محو ArrayBuffer الأصلية ولن تكون قابلة للاستخدام بعد ذلك. ويتم نقل محتواها (بشكل هادئ حرفيًا) إلى سياق "العاملين".

لاستخدام العناصر القابلة للنقل، يتوفّر إصدار جديد من postMessage() يتوافق مع العناصر القابلة للنقل:

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

في حالة العامل، تكون الوسيطة الأولى هي الرسالة ArrayBuffer. الوسيطة الثانية هي قائمة بالعناصر التي يجب نقلها. في هذا المثال، يمكنك تحديد arrayBuffer في القائمة القابلة للتحويل.

عرض توضيحي لمقياس الأداء

للاطّلاع على المكاسب على صعيد أداء الملفات القابلة للتحويل، أعددت عرضًا توضيحيًا.

يرسل العرض التوضيحي ملف ArrayBuffer بحجم 32 ميغابايت إلى العامل ويرسله مجددًا باستخدام postMessage(). وإذا كان متصفحك لا يتوافق مع العناصر القابلة للنقل، يتم استخدام الاستنساخ المنظّم في النموذج مرة أخرى. بمتوسط 5 عمليات تشغيل في متصفحات مختلفة، إليك ما حصلت عليه:

رسم بياني للمقارنة بين الاستنساخ المنظَّم والكائنات القابلة للتحويل

ففي جهاز MacBook Pro/10.6.8/2.53 غيغاهيرتز/Intel Core 2 Duo، كان FF الأسرع في استخدام الاستنساخ المنظم. في المتوسط، كان إرسال ArrayBuffer الذي يبلغ حجمه 32 ميغابايت إلى العامل وإرساله مرة أخرى إلى سلسلة التعليمات الرئيسية (RRT - مدة الذهاب والعودة). مقارنةً بالملفات القابلة للتحويل، استغرق الاختبار نفسه 6.6 ملي ثانية. هذا إنجاز كبير في الأداء.

يسمح توفُّر هذه السرعات بتمرير زخارف/شبكات WebGL ضخمة بين "العامل" والتطبيق الرئيسي.

اكتشاف الميزات

يصعب اكتشاف الميزات في هذه الحالة. نصيحتي لك هي إرسال 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() بالنسبة إلى النافذة والعامل. تاريخ التعديل (2016-11-03): تمت إزالة بادئات المورِّدين ومقتطفات الرموز المعدّلة