بدأ WebAssembly (WASM) كطريقة لتشغيل C++ في المتصفح. في عام 2026، يعمل في كل مكان - المتصفحات، الخوادم، شبكات الحافة، الأجهزة المدمجة - ويشغّل بعضاً من أكثر التطبيقات تطلباً على الويب. محرك العرض في Figma، وAdobe Photoshop على الويب، ومعالجة الفيديو في Google Meet، ومنصة الحوسبة الحافية في Cloudflare جميعها تعمل على WebAssembly.
وفقاً لـ Chrome Platform Status، يمثل WASM ما يقرب من 5.5% من جميع تحميلات صفحات Chrome في أوائل 2026، ارتفاعاً من 4.5% في العام السابق. مع أن WASM 3.0 أصبح معيار W3C ونضوج WASI نحو الإصدار 1.0، وصل النظام البيئي إلى نقطة تحول.
يغطي هذا الدليل كل ما تحتاج معرفته للبدء في البناء باستخدام WebAssembly.
ما هو WebAssembly؟
WebAssembly هو تنسيق تعليمات ثنائي مصمم كهدف للتجميع. تكتب الكود بلغة عالية المستوى (Rust, C, C++, Go, Kotlin)، تجمّعه إلى .wasm، وتشغّله في أي بيئة تحتوي على بيئة تشغيل WASM - المتصفحات، Node.js، Cloudflare Workers، Wasmtime، أو Wasmer.
كيف يعمل
WASM هو آلة افتراضية قائمة على المكدس (stack-based virtual machine). تدفع الدوال القيم وتسحبها من مكدس المعاملات. بيئة التشغيل المضيفة (V8 في Chrome، SpiderMonkey في Firefox) تجمّع بايت كود WASM إلى كود آلة أصلي بتقنية JIT، وهذا هو سبب أن الأداء قريب من الأداء الأصلي.
الخصائص الرئيسية:
- التنفيذ المعزول (Sandboxed execution): يمكن لوحدات WASM الوصول فقط إلى الموارد التي يمنحها المضيف صراحةً. لا نظام ملفات، لا شبكة، لا وصول لنظام التشغيل ما لم يُسمح بذلك. هذا مختلف جذرياً عن الكود الأصلي.
- الذاكرة الخطية (Linear memory):
ArrayBufferواحد متصل مشترك بين WASM والمضيف. البيانات المعقدة (النصوص، الهياكل) تُمرر بالكتابة في الذاكرة ومشاركة المؤشر. - محدود الأنواع (Type-limited): يدعم WASM أصلياً أربعة أنواع فقط:
i32،i64،f32،f64. كل شيء آخر (النصوص، المصفوفات، الكائنات) يتطلب الترميز عبر الذاكرة الخطية أو Component Model. - قابل للنقل (Portable): نفس ملف
.wasmالثنائي يعمل على أي منصة تحتوي على بيئة تشغيل WASM، دون إعادة تجميع.
WASM مقابل JavaScript
WASM لا يحل محل JavaScript. إنه يكمّله.
| الجانب | JavaScript | WebAssembly |
|---|---|---|
| التحليل | تحليل + تجميع أثناء التشغيل | ثنائي مجمّع مسبقاً، فك تشفير فقط |
| سرعة التنفيذ | محسّن بـ JIT، متغير | قريب من الأصلي، متسق |
| بدء التشغيل | سريع للنصوص الصغيرة | فك تشفير سريع، متوقع |
| وصول DOM | مباشر | غير مباشر (عبر كود JS الوسيط) |
| الأفضل لـ | UI، معالجة DOM، معالجة الأحداث | الحسابات كثيفة المعالج |
| جمع المخلفات | مدمج | WasmGC (جديد)، أو يدوي |
استخدم JavaScript لأعمال واجهة المستخدم وDOM. استخدم WASM للحسابات الثقيلة: معالجة الصور، ترميز الفيديو، محاكاة الفيزياء، التشفير، تحليل البيانات.
WASM 3.0: ما الجديد
أصبح WebAssembly 3.0 معيار W3C في سبتمبر 2025، حيث وحّد تسع ميزات كانت قيد التطوير لسنوات.
| الميزة | ما تتيحه |
|---|---|
| WasmGC | جمع مخلفات أصلي في WASM. اللغات المُدارة (Java, Kotlin, Dart) يمكنها التجميع إلى WASM دون شحن بيئة تشغيل GC خاصة بها. مدعوم في Chrome 119+، Firefox 120+، Safari 18.2+. |
| Exception Handling | try/catch أصلي في WASM. سابقاً، كانت الاستثناءات تتطلب رحلات ذهاب وإياب مكلفة إلى JavaScript. |
| Tail Calls | تمكين العودية الفعالة دون تجاوز المكدس. حاسم للغات الوظيفية. |
| Relaxed SIMD | تعليمات متجهات 128 بت لمعالجة البيانات المتوازية. تمكين تحسينات خاصة بالعتاد. |
| Memory64 | يكسر حد الذاكرة الخطية 4GB. مطلوب لمعالجة البيانات واسعة النطاق. |
| Multi-memory | مناطق ذاكرة مستقلة متعددة في وحدة واحدة. |
الأكثر تأثيراً هو WasmGC. قبله، كان تجميع Java أو Kotlin إلى WASM يعني شحن جامع مخلفات كامل كجزء من الملف الثنائي، مما يضخم حجم الملفات. الآن يتولى جامع المخلفات الخاص بالمتصفح إدارة الذاكرة لوحدات WASM، تماماً كما يفعل مع JavaScript.
WASI: WebAssembly خارج المتصفح
WASM في المتصفح قوي، لكن WASI (واجهة نظام WebAssembly) هو ما يجعل WASM بيئة تشغيل عالمية. يوفر WASI واجهات موحدة لموارد النظام - الملفات، الشبكات، الساعات، الأرقام العشوائية - مما يسمح لوحدات WASM بالعمل خارج المتصفح.
يحدد WASI Preview 2 (الإصدار المستقر الحالي) هذه الواجهات:
wasi:filesystem- عمليات الملفات عبر مقابض القدرات (ليس واصفات الملفات التقليدية)wasi:sockets- شبكات TCP/UDPwasi:http- معالجة طلبات/استجابات HTTPwasi:clocks- ساعة الحائط، الساعة الرتيبةwasi:random- عشوائية تشفيريةwasi:cli- وسائط سطر الأوامر، متغيرات البيئة، stdio
المبدأ الأساسي هو الأمان القائم على القدرات (capability-based security): لا يمكن لوحدة WASM الوصول إلى نظام الملفات ما لم يمنح المضيف صراحةً مقبضاً لمجلد محدد. هذا يجعل WASI أكثر أماناً جذرياً من تشغيل الملفات التنفيذية الأصلية.
الطريق إلى WASI 1.0
من المتوقع صدور WASI 0.3.0 (إضافة أوليات async/concurrency) في 2026، يليه WASI 1.0. الإضافة الرئيسية هي async مدمج في اللغة مع تدفق I/O بدون نسخ.
Component Model
وحدات WASM الأساسية يمكنها تبادل الأرقام فقط. Component Model يحل هذا القيد بإضافة نظام أنواع غني وطبقة قابلية التركيب فوق WASM.
WIT (أنواع واجهة WebAssembly)
WIT هي لغة تعريف واجهات تتيح للمكونات الإعلان عن وارداتها وصادراتها بأنواع غنية - نصوص، سجلات، قوائم، متغيرات، تعدادات - ليس فقط i32 و f64.
// calculator.wit package myorg:calculator@1.0.0; interface operations { record calculation { expression: string, result: f64, timestamp: u64, } add: func(a: f64, b: f64) -> f64; multiply: func(a: f64, b: f64) -> f64; history: func() -> list<calculation>; } world calculator { export operations; }
سلاسل الأدوات مثل wit-bindgen تولّد ربطاً خاصة باللغة من ملفات WIT. يمكن لمكون Rust ومكون Python تبادل النصوص والسجلات والقوائم عبر عقود WIT دون أن يعرف أي طرف لغة تنفيذ الطرف الآخر.
بناء أول وحدة WASM باستخدام Rust
يمتلك Rust أنضج أدوات WASM. لنبنِ مثالاً عملياً: وحدة معالجة صور تعمل في المتصفح.
الإعداد
# Install the WASM target for Rust rustup target add wasm32-unknown-unknown # Install wasm-pack (builds Rust to WASM + generates JS bindings) cargo install wasm-pack # Create a new library project cargo new --lib image-processor cd image-processor
تكوين Cargo.toml
[package] name = "image-processor" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2"
كتابة كود Rust
// src/lib.rs use wasm_bindgen::prelude::*; /// Convert an image buffer to grayscale. /// Input: RGBA pixel data as a flat u8 array (4 bytes per pixel). /// Output: Modified in place for zero-copy performance. #[wasm_bindgen] pub fn grayscale(pixels: &mut [u8]) { for chunk in pixels.chunks_exact_mut(4) { let r = chunk[0] as f32; let g = chunk[1] as f32; let b = chunk[2] as f32; // ITU-R BT.709 luminance coefficients let gray = (0.2126 * r + 0.7152 * g + 0.0722 * b) as u8; chunk[0] = gray; chunk[1] = gray; chunk[2] = gray; // chunk[3] is alpha, leave unchanged } } /// Adjust brightness of an image. /// factor > 1.0 brightens, < 1.0 darkens. #[wasm_bindgen] pub fn adjust_brightness(pixels: &mut [u8], factor: f32) { for chunk in pixels.chunks_exact_mut(4) { chunk[0] = ((chunk[0] as f32 * factor).min(255.0)) as u8; chunk[1] = ((chunk[1] as f32 * factor).min(255.0)) as u8; chunk[2] = ((chunk[2] as f32 * factor).min(255.0)) as u8; } } /// Invert all colors in the image. #[wasm_bindgen] pub fn invert(pixels: &mut [u8]) { for chunk in pixels.chunks_exact_mut(4) { chunk[0] = 255 - chunk[0]; chunk[1] = 255 - chunk[1]; chunk[2] = 255 - chunk[2]; } } /// Calculate the average brightness of an image (0-255). #[wasm_bindgen] pub fn average_brightness(pixels: &[u8]) -> f32 { let mut total: f64 = 0.0; let pixel_count = pixels.len() / 4; for chunk in pixels.chunks_exact(4) { let luminance = 0.2126 * chunk[0] as f64 + 0.7152 * chunk[1] as f64 + 0.0722 * chunk[2] as f64; total += luminance; } (total / pixel_count as f64) as f32 }
البناء
wasm-pack build --target web
ينتج هذا مجلد pkg/ يحتوي على:
image_processor_bg.wasm- الملف الثنائي المجمّع لـ WASMimage_processor.js- كود JavaScript الوسيط مع تعريفات TypeScriptpackage.json- جاهز للنشر على npm
الاستخدام في JavaScript
<!DOCTYPE html> <html> <head><title>WASM Image Processor</title></head> <body> <canvas id="canvas" width="800" height="600"></canvas> <button onclick="applyGrayscale()">Grayscale</button> <button onclick="applyBrightness()">Brighten</button> <button onclick="applyInvert()">Invert</button> <script type="module"> import init, { grayscale, adjust_brightness, invert } from "./pkg/image_processor.js"; let ctx; let imageData; async function setup() { await init(); const canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); // Load an image onto the canvas const img = new Image(); img.onload = () => { ctx.drawImage(img, 0, 0); imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); }; img.src = "photo.jpg"; } window.applyGrayscale = () => { grayscale(imageData.data); ctx.putImageData(imageData, 0, 0); }; window.applyBrightness = () => { adjust_brightness(imageData.data, 1.3); ctx.putImageData(imageData, 0, 0); }; window.applyInvert = () => { invert(imageData.data); ctx.putImageData(imageData, 0, 0); }; setup(); </script> </body> </html>
الرؤية الأساسية: imageData.data هو Uint8ClampedArray مدعوم بـ ArrayBuffer. عند تمريره إلى WASM، يتشارك نفس الذاكرة - بدون نسخ. تعدّل دالة Rust البكسلات في مكانها، ويرى جانب JavaScript التغييرات فوراً.
المستوى الأدنى: إنشاء مثيل WASM يدوياً
إذا كنت لا تريد استخدام wasm-bindgen، يمكنك إنشاء مثيلات وحدات WASM مباشرة:
const response = await fetch("calculator.wasm"); const { instance } = await WebAssembly.instantiateStreaming(response, { env: { // Functions the WASM module can call log_result: (value) => console.log("Result:", value), }, }); // Call exported functions const { add, multiply } = instance.exports; console.log(add(5, 3)); // 8 console.log(multiply(4, 7)); // 28
هذا مفيد عندما تريد الحد الأدنى من الحمل الزائد ولا تحتاج إلى تكامل أنواع غني.
الأداء: WASM مقابل JavaScript
تُظهر المعايير الواقعية تسريعات كبيرة للمهام كثيفة المعالج:
| المهمة | JavaScript | WASM | التسريع |
|---|---|---|---|
| معالجة صور 4K | 180ms | 8ms (مع SIMD) | 22x |
| تغيير حجم صورة (4K) | 250ms | 45ms | 5.5x |
| محاكاة فيزياء (10K كيان) | إسقاط إطارات | 60fps سلس | ~10x |
| تحليل JSON (حمولة كبيرة) | 12ms | 3ms | 4x |
| تجزئة تشفيرية | 45ms | 6ms | 7.5x |
يعمل WASM بحوالي 95% من سرعة الكود الأصلي. أكبر المكاسب تأتي من:
- أداء متوقع (لا إحماء JIT، لا توقفات GC)
- تعليمات SIMD لمعالجة البيانات المتوازية
- وصول مباشر للذاكرة دون تدخل جامع المخلفات
حيث لا يكون WASM أسرع: معالجة DOM، الحسابات الصغيرة، المهام المقيدة بالإدخال/الإخراج. JavaScript محسّن بالفعل لهذه الأمور.
حالات الاستخدام الإنتاجية
Figma: عرض متجهات في الوقت الحقيقي
محرك العرض الأساسي في Figma هو C++ مجمّع إلى WASM. كل شكل، تدرج، وتأثير يُحسب في WASM ويُرسم على عنصر Canvas. هذا يتيح لـ Figma التعامل مع تصميمات معقدة بآلاف الطبقات بمعدل 60fps في المتصفح - أداء يستحيل تحقيقه بـ JavaScript فقط.
Adobe Photoshop على الويب
نقلت Adobe مرشحات وأدوات Photoshop الرئيسية إلى WASM باستخدام Rust. تُظهر معاييرهم معالجة صور 4K في 22ms مع WASM SIMD مقابل 180ms في JavaScript - تحسين 8x يجعل معاينة المرشحات في الوقت الحقيقي ممكنة.
Cloudflare Workers
يشغّل Cloudflare وحدات WASM في عزلات V8 عبر أكثر من 330 موقعاً حافياً. بدايات التشغيل الباردة هي 1-5ms (مقارنة بـ 100-500ms للخوادم بدون خادم المعتمدة على الحاويات). في فبراير 2026، نشروا استدلال Llama-3-8b عبر شبكتهم الحافية باستخدام WASM.
Google Meet
التمويه الخلفي والخلفيات الافتراضية في Google Meet تستخدم WASM مع SIMD لمعالجة الفيديو في الوقت الحقيقي. تعالج وحدة WASM كل إطار فيديو بسرعة كافية للحفاظ على فيديو سلس بمعدل 30fps.
دعم المتصفحات (2026)
| الميزة | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Core WASM | كامل | كامل | كامل | كامل |
| Threads | نعم | نعم | نعم | نعم |
| SIMD (128-bit) | نعم | نعم | نعم | نعم |
| WasmGC | 119+ | 120+ | 18.2+ | نعم |
| Exception Handling | نعم | نعم | نعم | نعم |
| Memory64 | نعم | نعم | جزئي | نعم |
جميع المتصفحات الرئيسية تدعم WASM بالكامل. الميزات الأحدث (WasmGC, Exception Handling) وصلت إلى توفر واسع.
مرجع الأدوات
| الأداة | الغرض | التثبيت |
|---|---|---|
| wasm-pack | بناء Rust إلى WASM، توليد حزم npm | cargo install wasm-pack |
| wasm-bindgen | ربط تكامل Rust/JS (يستخدمه wasm-pack) | تبعية في Cargo.toml |
| wasm-opt | تحسين حجم الملف الثنائي (تقليل 50%+) | جزء من Binaryen: brew install binaryen |
| wit-bindgen | توليد ربط من ملفات WIT | cargo install wit-bindgen-cli |
| Wasmtime | بيئة تشغيل WASM على جانب الخادم (تطبيق WASI المرجعي) | brew install wasmtime |
| Wasmer | بيئة تشغيل WASM بديلة مع دعم WASI | curl https://get.wasmer.io -sSfL | sh |
| wasm-feature-detect | كشف ميزات المتصفح أثناء التشغيل | npm install wasm-feature-detect |
تحسين حجم الملف الثنائي
يمكن أن تكون ملفات WASM الثنائية كبيرة. إليك كيفية تقليصها:
# Cargo.toml [profile.release] opt-level = "z" # Optimize for size lto = true # Link-time optimization codegen-units = 1 # Better optimization, slower compile strip = true # Strip debug symbols
# Build in release mode wasm-pack build --release --target web # Further optimize with wasm-opt wasm-opt -Oz pkg/image_processor_bg.wasm -o pkg/image_processor_bg.wasm
وحدة Rust WASM نموذجية تنخفض من 500KB إلى أقل من 50KB مع هذه التحسينات.
خارطة طريق البدء
الخلاصة
WebAssembly لم يعد تجريبياً. إنه تقنية إنتاجية تستخدمها بعض أكثر التطبيقات تطلباً على الويب. أداء قريب من الأصلي، أمان معزول، وقابلية نقل عالمية - لا يوجد هدف تجميع آخر يمنحك الثلاثة.
لست بحاجة لإعادة كتابة تطبيقك بالكامل بـ WASM. ابدأ بدالة واحدة كثيفة المعالج - مرشح صور، محلل بيانات، حساب فيزيائي - جمّعها إلى WASM، واستدعها من JavaScript. قِس الفرق. ثم قرر أين يمكن لـ WASM المساعدة أيضاً.
الأدوات ناضجة، دعم المتصفحات عالمي، والنظام البيئي ينمو. إذا كنت تكتب Rust، فأنت بالفعل على بُعد أمر واحد من المتصفح.
قائمة مراجعة البدء:
- تثبيت Rust وwasm-pack
- بناء أول وحدة WASM وتشغيلها في المتصفح
- تكامل JavaScript يعمل (استدعاء WASM من JS)
- بناء إصدار بتحسينات الحجم مطبقة
- قياس الأداء مقارنة بمكافئ JavaScript الخالص
- استكشاف WASI مع Wasmtime لحالات استخدام جانب الخادم