WebAssembly از مرورگر فرار کرد؛ اینجا جاییست که در ۲۰۲۶ واقعاً اجرا میشود

WebAssembly در سال ۲۰۱۷ معرفی شد تا کدهای کامپایل شده را در مرورگرها با سرعت نزدیک به native اجرا کند. در سال ۲۰۲۶، این داستان اولیه تقریباً یک پاورقی شده. داستان جذابتر اتفاقاتی است که خارج از مرورگر افتاده. Wasm حالا در توابع serverless، گرههای edge، سیستمهای پلاگین و افزونههای دیتابیس اجرا میشود. Wasm Component Model و WASI 0.2 این ساختار را در ۲۰۲۴ رسمی کردند و اکوسیستم کاملاً بهروز شده.
یک مرور سریع: Wasm دقیقاً چیست
WebAssembly یک فرمت دستورالعمل باینری است که برای اجرا در یک ماشین مجازی sandboxed طراحی شده. میتوان از زبانهای C، C++، Rust، Go، Swift، Kotlin و لیست رو به رشد زبانهای دیگر کامپایلش کرد. سه ویژگی آن را منحصربهفرد کرده:
- اجرای قطعی — همان باینری در هر پلتفرم و هر بار خروجی یکسانی تولید میکند.
- ایزولهسازی حافظه — یک ماژول Wasm بدون اجازه صریح از طریق رابط، به سیستمعامل میزبان، فایلسیستم یا شبکه دسترسی ندارد.
- قابلیت حمل معماری — همان فایل
.wasmروی x86، ARM و RISC-V بدون نیاز به کامپایل مجدد اجرا میشود.
از نظر اندازه، یک ماژول Wasm معمولی ۱۰ تا ۱۰۰ برابر کوچکتر از یک تصویر کانتینر Docker معادل است. در زمان راهاندازی، runtimeهای Wasm در میکروثانیه مقداردهی میشوند — در مقایسه با صدها میلیثانیه یا ثانیه برای کانتینرها. اینها مزیتهای حاشیهای نیستند؛ بلکه تغییر میدهند که چه چیزی در edge از نظر اقتصادی مقرونبهصرفه است.
WASI 0.2 و Component Model — چرا مهم هستند
WASI (WebAssembly System Interface) یک API استاندارد است که به ماژولهای Wasm اجازه میدهد با دنیای خارج تعامل کنند — I/O فایل، شبکه، ساعت، تصادفی. WASI 0.1 بهعمد حداقلی بود. WASI 0.2 که در ژانویه ۲۰۲۴ تصویب شد، درخواستها و پاسخهای HTTP، سوکتها، اولیههای رمزنگاری و مهمتر از همه Component Model را اضافه کرد.
Component Model مشخص میکند که ماژولهای Wasm چگونه با یکدیگر ترکیب شوند. یک کامپوننت Rust میتواند با استفاده از یک رابط تایپدار که در WIT (Wasm Interface Types) تعریف شده، یک کامپوننت Python را صدا بزند. این کار با سربار FFI صفر و تضمین نوع قوی در مرز انجام میشود. قبل از این، ماژولهای Wasm واحدهای ایزوله بودند — مفید اما غیرقابل ترکیب. Component Model همان چیزی است که Wasm را به یک پلتفرم واقعی تبدیل میکند، نه فقط یک هدف کامپایل.
نتیجه عملی: حالا میتوانید یک برنامه Wasm را با ترکیب کامپوننتهای مستقل توسعهیافته، نوشته شده به زبانهای مختلف، که در سطح رابط به هم متصل میشوند، بسازید. بدون حافظه مشترک، بدون کابوسهای سازگاری ABI.
Runtimeهای سمت سرور: Wasmtime، Wasmer، WasmEdge
سه runtime بهعنوان انتخابهای جدی تولید برای Wasm سمت سرور ظهور کردهاند:
- Wasmtime (Bytecode Alliance، نوشته شده با Rust): درجه تولید، کاملاً منطبق با WASI 0.2، در تولید توسط Fastly و Shopify استفاده میشود. پیادهسازی مرجع برای مشخصات Wasm.
- Wasmer: از WASIX پشتیبانی میکند — یک WASI گسترشیافته با syscallهای شبه POSIX که به برنامههای بیشتر سبک Unix اجازه میدهد بدون تغییر اجرا شوند. همچنین تصاویر Wasm سازگار با Docker را از طریق رجیستری Wasmer میزبانی میکند.
- WasmEdge: یک پروژه sandbox CNCF که برای بارهای کاری inference AI بهینه شده. GGML و llama.cpp کامپایل شده به Wasm را اجرا میکند و آن را به runtime انتخابی برای استقرارهای edge AI تبدیل کرده که در آن Docker سنگین است.
فراتر از runtimeها، Spin از Fermyon یک فریمورک میکروسرویس است که به صورت بومی روی Wasm ساخته شده — اساساً AWS Lambda اما با معنای اجرای Wasm، کامپوننتهای WASI 0.2 و بدون مشکل cold start.
Edge Compute: مورد استفاده قاتل
اگر میخواهید بفهمید چرا ارائهدهندگان edge قبل از بقیه Wasm را پذیرفتند، به اقتصاد آن نگاه کنید: در edge، شما هزاران تابع مشتری را روی زیرساخت اشتراکی اجرا میکنید و به طور همزمان به ایزولهسازی، راهاندازی سریع و سربار حافظه کم نیاز دارید. کانتینرها ایزولهسازی را حل میکنند اما در زمان راهاندازی و سربار هر تابع شکست میخورند. VMها بدتر هستند. Wasm هر سه را حل میکند.
- Cloudflare Workers از V8 isolates با پشتیبانی کامل Wasm استفاده میکند. توابع در کمتر از ۱ میلیثانیه شروع میشوند. بیش از ۲ میلیون توسعهدهنده کد Workers را مستقر کردهاند.
- Fastly Compute از Wasmtime با کامپایل AOT (ahead-of-time) استفاده میکند. زمان cold start به معنای واقعی ۰ میلیثانیه است — ماژول هنگام رسیدن درخواست از قبل به کد native کامپایل شده است. یک تابع Rust که به Wasm کامپایل شده، با ۵ تا ۱۰٪ سرعت اجرای native اجرا میشود.
- Vercel Edge Functions از ماژولهای Wasm به عنوان شهروندان درجه یک در کنار JavaScript پشتیبانی میکند.
مدل sandbox در اینجا باربر است: کدهای ارائهشده توسط کاربر و غیرقابل اعتماد روی زیرساخت edge اشتراکی بدون سربار کانتینر اجرا میشود، زیرا تضمینهای ایزولهسازی Wasm در سطح VM اعمال میشود، نه سطح OS. برای هر مستأجر نیازی به فضای نام هسته جداگانه ندارید.
سیستمهای پلاگین: بدون سازش توسعه دهید
مشکل سنتی پلاگین: میخواهید به کاربران اجازه دهید پلتفرم شما را گسترش دهند، اما اجرای کد دلخواه در داخل فرایند شما یک فاجعه امنیتی است. گزینههای تاریخی عبارت بودند از: ایزولهسازی زیرفرایند (کند و پیچیده)، یک زبان اسکریپتنویسی سفارشی (محدود)، یا فقط پذیرش ریسک (بد). Wasm این را حل میکند.
- Extism یک سیستم پلاگین متنباز است که روی Wasm ساخته شده. شما یک فایل
.wasmرا به عنوان پلاگین ارسال میکنید؛ میزبان آن را به طور ایمن در یک محیط ایزوله با فقط رابطهایی که شما به صراحت در معرض قرار دادهاید، بارگذاری میکند. HashiCorp از آن برای پلاگینهای Vault، Grafana برای پلاگینهای منبع داده، و چندین موتور بازی برای سیستمهای مدینگ استفاده میکنند. - افزونههای چکاوت Shopify به عنوان ماژولهای Wasm اجرا میشوند. کد ارائهشده توسط فروشنده داخل زیرساخت Shopify اجرا میشود و هیچ توانایی برای خروج داده یا دسترسی به سیستمهای خارج از رابط تعریف شده ندارد. این فقط به این دلیل ممکن است که sandboxing Wasm آن را به طور پیشفرض ایمن میکند.
- Zed (ویرایشگر کد مبتنی بر Rust) از Wasm برای افزونهها استفاده میکند. نیازی به Node.js runtime نیست، زنجیره وابستگی npm نیست، مدیریت فرایند افزونه نیست. افزونهها به صورت ایزوله در Wasm با یک رابط میزبان خوب تعریف شده اجرا میشوند.
الگو تعمیم مییابد: هر پلتفرمی که کد ارائهشده توسط کاربر را میپذیرد میتواند "ریسک اجرای کد دلخواه" را با "اجرای Wasm در یک رابط تعریف شده" جایگزین کند و امنیت، قابلیت حمل و انعطافپذیری زبان را همزمان به دست آورد.
افزونههای دیتابیس
افزونه آزمایشی pg_wasm PostgreSQL به توابع تعریفشده توسط کاربر (UDF) نوشته شده به هر زبانی که به Wasm کامپایل میشود، اجازه میدهد. SingleStore از UDFهای Wasm در تولید پشتیبانی میکند. ارزش پیشنهادی مستقیم است: یک UDF حیاتی از نظر عملکرد را با Rust بنویسید، به Wasm کامپایل کنید، بدون کامپایل مجدد باینری دیتابیس و بدون نصب Rust toolchain روی سرور دیتابیس مستقر کنید. sandbox Wasm همچنین به این معنی است که یک UDF اشکالدار نمیتواند حافظه دیتابیس را خراب کند — در فضای حافظه خطی خودش اجرا میشود.
برای بارهای کاری تحلیلی، این در را به روی aggregates سفارشی با عملکرد بالا و transformations باز میکند که قبلاً نیاز به افزونههای C داشتند یا با PL/pgSQL کند نوشته میشدند.
AI Inference در Wasm
WasmEdge ترکیب شده با llama.cpp کامپایل شده به Wasm میتواند inference LLM را روی هر میزبان WasmEdge اجرا کند. سربار در مقایسه با اجرای native تقریباً ۱۵ تا ۲۵٪ است — قابل توجه، اما برای بسیاری از موارد استفاده قابل قبول. مزیت آن قابلیت حمل است: همان باینری Wasm روی سرور ابری x86، گره edge ARM یا دستگاه IoT RISC-V بدون کامپایل مجدد اجرا میشود.
این در زمینههای IoT و edge AI جاسازی شده که اجرای Docker به دلیل محدودیت ذخیرهسازی و حافظه غیرعملی است، مهم است. یک مدل ۷B کوانتایز ۴ بیتی که از طریق WasmEdge روی یک دستگاه edge اجرا میشود، یک الگوی استقرار واقعی در سال ۲۰۲۶ است، نه یک دمو.
Wasm هنوز در چه کارهایی خوب نیست
محدودیتهای Wasm واقعی هستند و ارزش نام بردن دارند:
- چندرشتهای در حال بهبود است — پیشنهاد threads و حافظه مشترک در مشخصات هستند — اما نوشتن Wasm چندرشتهای صحیح هنوز از threading بومی سختتر است و پشتیبانی runtime متفاوت است.
- زبانهای garbage-collected (Go، Python، JavaScript) باینریهای Wasm بزرگتری تولید میکنند زیرا runtime GC باید کامپایل شود. یک باینری Wasm Go معمولاً ۵ تا ۱۵ مگابایت است. این با بلوغ یکپارچهسازی GC در حال کاهش است، اما امروز واقعی است.
- اشکالزدایی تولید از کد بومی سختتر است. source map کمک میکند، اما stack traceها در Wasm هنوز کمتر از اشکالزدایی بومی ارگونومیک هستند.
- زنجیرههای ابزار Java و .NET هنوز در حال بلوغ هستند. Java بکاندهای آزمایشی Wasm دارد و .NET Blazor برای Wasm مرورگر دارد، اما .NET سمت سرور به Wasm برای موارد استفاده عمومی هنوز درجه تولید نیست.
نتیجهگیری
منشأ مرورگری Wasm یک تصادف تاریخی بود — یک میزبان مناسب که sandboxing، یک لایه همکاری JS و یک محیط استاندارد فراهم میکرد. آنچه مرورگر در واقع ساخت یک واحد اجرای جهانی، قابل حمل و sandboxed بود که اتفاقاً در سرورها، گرههای edge، دیتابیسها و میزبانهای پلاگین هم کار میکند.
Component Model سرانجام به Wasm معنای ترکیب را داد تا به عنوان یک پلتفرم نرمافزاری واقعی عمل کند — ماژولهایی با رابطهای تایپدار، قابل ترکیب بدون حافظه مشترک یا پیچیدگی FFI. WASI 0.2 مدل دسترسی به سیستم را داد تا در زمینههای غیرمرورگر مفید باشد. runtimeها و ابزارها بهروز شدهاند.
سوال حالا این نیست که آیا Wasm مهم خواهد بود. همین الان در CDN شما، احتمالاً در افزونههای IDE شما و به طور فزاینده در دیتابیس شما اجرا میشود. سوال این است که کدام مورد استفاده آن را برای استک شما اجتنابناپذیر میکند — و برای بیشتر تیمها، آن لحظه نزدیکتر از چیزی است که انتظار دارند.