WebAssembly (WASM) به عنوان راهی برای اجرای C++ در مرورگر آغاز شد. در سال 2026، همه جا اجرا میشود - مرورگرها، سرورها، شبکههای لبه، دستگاههای تعبیهشده - و برخی از پرتقاضاترین اپلیکیشنهای وب را تامین میکند. موتور رندر Figma، Adobe Photoshop روی وب، پردازش ویدیوی Google Meet، و پلتفرم محاسبات لبه Cloudflare همگی روی WebAssembly اجرا میشوند.
طبق Chrome Platform Status، WASM در اوایل 2026 حدود 5.5% از تمام بارگذاریهای صفحات Chrome را تشکیل میدهد، که از 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) است. توابع مقادیر را روی یک پشته عملوند push و pop میکنند. محیط اجرای میزبان (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 |
|---|---|---|
| تجزیه | Parse + compile در زمان اجرا | باینری از پیش کامپایل شده، فقط decode |
| سرعت اجرا | بهینهشده با JIT، متغیر | نزدیک به بومی، ثابت |
| راهاندازی | سریع برای اسکریپتهای کوچک | decode سریع، قابل پیشبینی |
| دسترسی DOM | مستقیم | غیرمستقیم (از طریق کد واسط JS) |
| بهترین برای | UI، دستکاری DOM، مدیریت رویداد | محاسبات فشرده CPU |
| جمعآوری زباله | داخلی | WasmGC (جدید)، یا دستی |
برای کار UI و DOM از JavaScript استفاده کنید. برای محاسبات سنگین از WASM استفاده کنید: پردازش تصویر، رمزگذاری ویدیو، شبیهسازی فیزیک، رمزنگاری، تجزیه داده.
WASM 3.0: چه چیزی جدید است
WebAssembly 3.0 در سپتامبر 2025 به استاندارد W3C تبدیل شد و نه ویژگی را که سالها در حال توسعه بودند استاندارد کرد.
| ویژگی | چه چیزی را فعال میکند |
|---|---|
| WasmGC | جمعآوری زباله بومی در WASM. زبانهای مدیریتشده (Java, Kotlin, Dart) میتوانند بدون ارسال محیط اجرای GC خود به WASM کامپایل شوند. در 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 به معنای ارسال یک جمعکننده زباله کامل به عنوان بخشی از باینری بود که حجم فایلها را بالا میبرد. اکنون GC خود مرورگر مدیریت حافظه را برای ماژولهای 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- باینری WASM کامپایل شدهimage_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
معیارهای واقعی تسریع قابل توجهی را برای وظایف فشرده CPU نشان میدهند:
| وظیفه | 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، محاسبات کوچک، وظایف محدود به I/O. JavaScript قبلاً برای اینها بهینه شده است.
موارد استفاده پروداکشن
Figma: رندر بردار در زمان واقعی
موتور رندر اصلی Figma، C++ کامپایل شده به WASM است. هر شکل، گرادیان و افکت در WASM محاسبه میشود و روی یک عنصر Canvas رسم میشود. این به Figma اجازه میدهد طراحیهای پیچیده با هزاران لایه را با 60fps در مرورگر مدیریت کند - عملکردی که در JavaScript خالص غیرممکن خواهد بود.
Adobe Photoshop روی وب
Adobe فیلترها و ابزارهای کلیدی Photoshop را با استفاده از Rust به WASM منتقل کرد. معیارهای آنها پردازش تصویر 4K در 22ms با WASM SIMD در مقابل 180ms در JavaScript را نشان میدهد - بهبود 8 برابری که پیشنمایش فیلتر در زمان واقعی را ممکن میسازد.
Cloudflare Workers
Cloudflare ماژولهای WASM را در ایزولههای V8 در بیش از 330 مکان لبه اجرا میکند. راهاندازی سرد 1-5ms است (در مقایسه با 100-500ms برای serverless مبتنی بر کانتینر). در فوریه 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 بازنویسی کنید. با یک تابع فشرده CPU شروع کنید - یک فیلتر تصویر، یک تجزیهکننده داده، یک محاسبه فیزیک - آن را به WASM کامپایل کنید و از JavaScript فراخوانی کنید. تفاوت را اندازه بگیرید. سپس تصمیم بگیرید WASM کجای دیگر میتواند کمک کند.
ابزارها بالغ هستند، پشتیبانی مرورگر جهانی است، و اکوسیستم در حال رشد است. اگر Rust مینویسید، از قبل فقط یک دستور با مرورگر فاصله دارید.
چکلیست شروع:
- Rust و wasm-pack نصب شدهاند
- اولین ماژول WASM ساخته شده و در مرورگر اجرا میشود
- تعامل JavaScript کار میکند (فراخوانی WASM از JS)
- بیلد انتشار با بهینهسازیهای حجم اعمال شده
- عملکرد در مقایسه با معادل JavaScript خالص معیارسنجی شده
- WASI با Wasmtime برای موارد استفاده سمت سرور بررسی شده