WebAssembly از مرورگر خارج شد — و به زمان اجرای جهانی برای رایانش لبه تبدیل میشود

WebAssembly در سال ۲۰۱۷ در مرورگرها به عنوان یک هدف کامپایل برای کدهای حیاتی از نظر عملکرد عرضه شد — راهی برای اجرای C، C++ یا Rust با سرعتی که JavaScript برای بارهای کاری محاسباتی سنگین نمیتواند ارائه دهد. در چند سال اول، گفتوگو تقریباً به طور کامل حول موارد استفاده در مرورگر بود: موتورهای بازی، پردازش تصویر، کدکهای ویدیویی. این چارچوببندی به آرامی منسوخ شده است. در سال ۲۰۲۶، برخی از فعالترین استقرارهای WebAssembly هیچ ارتباطی با مرورگرها ندارند.
Cloudflare Workers بیش از ۵۰ میلیون درخواست در ثانیه را در ۳۰۰ مکان لبه پردازش میکند، با Wasm به عنوان یک هدف اجرایی درجهیک در کنار JavaScript. پلتفرم Compute@Edge فستلی — که کاملاً حول Wasm ساخته شده — ترافیک تولیدی را برای مشتریانی پردازش میکند که به شروع سرد زیر میلیثانیه نیاز دارند، چیزی که سرورلس مبتنی بر کانتینر نمیتواند ارائه دهد. پایگاههای داده مانند SQLite (از طریق libsqlite-wasm)، ابزارهای مشاهدهپذیری، و سیستمهای افزونه در ویرایشگرها و موتورهای بازی، Wasm را به عنوان یک زمان اجرای افزونه ایمن و قابل حمل مستقر میکنند. این فناوری تناسب محصول-بازار را در خارج از بافتی که برای آن طراحی شده بود پیدا کرده است.
چه چیزی Wasm را به عنوان یک زمان اجرا جذاب میکند
سه ویژگی WebAssembly را از گزینههای جایگزین مانند کانتینرها، باینریهای بومی یا بایتکد JVM متمایز میکند.
قابلیت حمل باینری. یک فایل .wasm یک فرمت باینری فشرده با یک مجموعه دستورالعمل کاملاً مشخص است. یک بار از Rust، C، Go، Swift، Python یا هر زبانی که هدف Wasm دارد کامپایل کنید، و همان باینری روی هر میزبانی که یک زمان اجرای سازگار دارد اجرا میشود — x86، ARM، RISC-V، صرفنظر از سیستمعامل. این همان وعدهای است که JVM در دهه ۱۹۹۰ داد، اما بدون سربار GC یا نیاز به نصب زمان اجرای مختص پلتفرم.
سرعت اجرای نزدیک به بومی. مجموعه دستورالعمل Wasm به گونهای طراحی شده که مستقیماً با کمترین سربار به کد ماشین کامپایل شود. زمانهای اجرای مدرن از کامپایل لایهای استفاده میکنند: یک کامپایلر پایه سریع تأخیر شروع سرد را مدیریت میکند، یک کامپایلر بهینهساز مبتنی بر Cranelift یا LLVM برای توابع داغ وارد عمل میشود. نتایج بنچمارک از Bytecode Alliance نشان میدهد که Wasm برای بارهای کاری محدود به CPU در حدود ۱.۵–۲ برابر کد بومی معادل اجرا میشود — بسیار بهتر از زبانهای تفسیر شده و قابل رقابت با محیطهای JIT-compiled.
محفظهسازی قطعی. هر ماژول Wasm در یک محفظه ایزوله از حافظه اجرا میشود. نمیتواند به حافظه میزبان خارج از منطقه حافظه خطی خود دسترسی داشته باشد. نمیتواند مستقیماً فراخوانی سیستم انجام دهد. نمیتواند بدون اجازه صریح از میزبان، رشتهها را ایجاد کند یا توصیفگرهای فایل را باز کند. این تئاتر امنیتی نیست — در سطح دستورالعمل توسط زمان اجرا اعمال میشود. همان مدل ایزولهسازی که از سوءاستفادههای مرورگر جلوگیری کرد، Wasm را به یک سیستم افزونه جذاب تبدیل میکند: میتوانید کد شخص ثالث غیرقابل اعتماد را بارگذاری کنید، دقیقاً قابلیتهایی که میخواهید به آن بدهید و بقیه را محفظهسازی کنید.
WASI: قطعه گمشده برای اجرای Wasm در خارج از مرورگرها
یک ماژول Wasm در مرورگر رابط سیستم خود را از JavaScript دریافت میکند — میزبان APIهایی برای دسترسی به DOM، شبکه و ذخیرهسازی ارائه میدهد. در خارج از مرورگر، هیچ میزبانی JavaScript وجود ندارد. این شکافی است که WASI — رابط سیستم WebAssembly — برای پر کردن آن طراحی شده است.
WASI یک سطح API مبتنی بر قابلیت برای دسترسی به سیستم فایل، ساعتها، تولید اعداد تصادفی، سوکتهای شبکه و متغیرهای محیطی تعریف میکند. یک باینری Wasm که بر اساس WASI کامپایل شده میتواند فایلها را باز کند، متغیرهای محیطی را بخواند و با استفاده از یک رابط استاندارد شده بر روی stdout بنویسد — و زمان اجرای میزبان در زمان نمونهسازی تصمیم میگیرد که کدام قابلیتها را واقعاً اعطا کند. همان باینری بدون کامپایل مجدد روی یک سرور لینوکس در Wasmtime و روی یک میزبان Wasm سمت مرورگر اجرا میشود؛ فقط اعطای قابلیتها متفاوت است.
WASI Preview 2، که در سال ۲۰۲۴ نهایی شد و از طریق ۲۰۲۵–۲۰۲۶ پذیرش گسترده زمان اجرا را میبیند، پیشرفت قابلتوجهتری است. این نسخه مدل مؤلفه را معرفی میکند — راهی برای ترکیب چند ماژول Wasm با رابطهای تایپشده با استفاده از یک زبان تعریف رابط جدید به نام WIT (Wasm Interface Types). به جای عبور دادن اشارهگرهای حافظه خام بین ماژولها، مؤلفهها APIهای به شدت تایپشده را در معرض دید قرار میدهند. یک مؤلفه که تصاویر را پردازش میکند میتواند اعلام کند که image: png-image را میپذیرد و thumbnail: jpeg-image را برمیگرداند، و زمان اجرای Wasm میتواند آن را به هر مؤلفه دیگری که همان نوعها را صحبت میکند متصل کند، صرفنظر از اینکه هر یک از چه زبانی کامپایل شدهاند. این قطعهای است که «از Rust کامپایل کن، از Python صدا بزن» را واقعاً ترکیبپذیر میکند، نه صرفاً از نظر تئوری امکانپذیر.
زمانهای اجرا و پلتفرمها
اکوسیستم زمان اجرا از روزهای اولیه آزمایش صرفاً با node به طور قابلتوجهی تکامل یافته است.
Wasmtime، که توسط Bytecode Alliance — یک نهاد استاندارد که اعضای آن شامل Mozilla، Fastly، Intel، Microsoft و Google هستند — نگهداری میشود، پیادهسازی مرجع برای WASI است. به زبان Rust نوشته شده و از مولد کد Cranelift برای کامپایل بهینه استفاده میکند. Wasmtime زمان اجرای زیربنایی Fastly Compute@Edge است و به طور گسترده برای جاسازی Wasm در برنامههای سرور استفاده میشود. CLI (wasmtime run module.wasm) آزمایش باینریهای Wasm را به صورت محلی آسان میکند.
WasmEdge، یک پروژه CNCF Sandbox، بارهای کاری ابری-بومی و هوش مصنوعی را هدف قرار میدهد. این پروژه از طریق یک پیادهسازی بومی wasi-nn از استنتاج مدل ONNX پشتیبانی درجهیک دارد و آن را به زمان اجرای مرجع برای موارد استفاده هوش مصنوعی در لبه تبدیل میکند. WasmEdge با containerd یکپارچه میشود و میتواند به عنوان یک جایگزین سبکوزن برای یک زمان اجرای کامل کانتینر برای بارهای کاری Wasm در کلاسترهای Kubernetes استفاده شود — یک الگوی استقرار که از سربار یک userland کامل لینوکس در هر بار کاری جلوگیری میکند.
Wasmer رویکرد متفاوتی دارد: جاسازی زبان-بومی را اولویت میدهد، با SDK برای Rust، Python، Go، Java، PHP و Ruby که به شما امکان میدهد ماژولهای Wasm را از کد زبان میزبان با حداقل کد قالبی نمونهسازی و فراخوانی کنید. Wasmer همچنین WASIX — یک پسوند WASI که تردینگ سازگار با POSIX، ایجاد فرآیند و primitives پایپ را اضافه میکند — ارائه میدهد و برنامههای Unix-like بیشتری را قادر میسازد بدون تغییر به Wasm کامپایل شوند.
Spin، ساخته شده توسط Fermyon، یک چارچوب برنامهای است که برای میکروسرویسهای Wasm طراحی شده است. در جایی که Wasmtime یک زمان اجرا است که جاسازی میکنید، Spin یک پلتفرم است که روی آن میسازید — مؤلفههای خود را در یک مانیفست spin.toml تعریف کنید، هندلرها را در Rust، Go یا Python پیادهسازی کنید، و Spin مسیردهی HTTP، ذخیرهسازی کلید-مقدار، دسترسی SQL و pub/sub را از طریق APIهای بومی Wasm مدیریت میکند. Fermyon Cloud برنامههای Spin را مستقیماً اجرا میکند؛ این چارچوب میتواند از طریق Spin Operator به Kubernetes نیز مستقر شود.
در سمت پلتفرم، Cloudflare Workers پیشگام Wasm-at-the-edge به عنوان یک سرویس تولیدی بود. Workers از V8 isolates با پشتیبانی Wasm برای دستیابی به زمان شروع سرد کمتر از ۵ میلیثانیه در سطح جهانی استفاده میکند — رقمی که توابع Lambda مبتنی بر کانتینر نمیتوانند به آن نزدیک شوند. Fastly Compute@Edge فراتر میرود: هر نمونه Compute یک ماژول Wasm است، بدون هیچ زمان اجرای JavaScript، که امکان اجرای زیر میلیثانیه منطق رسیدگی به درخواست را در گرههای لبه Fastly فراهم میکند.
موارد استفاده واقعی در سال ۲۰۲۶
سیستمهای افزونه بدون شک از نظر گستردگی استقرار موفقترین مورد استفاده غیر-مرورگر Wasm هستند. Extism (توسط Dylibso) یک سیستم افزونه منبع باز است که بر Wasm ساخته شده: یک میزبان Extism کوچک را در برنامه خود جاسازی کنید، و هر شخص ثالثی میتواند افزونههایی در Rust، Go، Python یا TypeScript بنویسد که در یک محیط Wasm محفظهسازی شده با قابلیتهای اعلام شده اجرا شوند. پروژههایی مانند ویرایشگر Zed، WasmCloud و چندین افزونه پایگاه داده از این الگو استفاده میکنند. مدل ایزولهسازی Wasm مشکل اعتماد نویسنده افزونه را که دههها سیستمهای افزونه بومی را آزار داده حل میکند.
توابع لبه پرحجمترین استقرار هستند. Cloudflare Workers روزانه میلیاردها درخواست را با استفاده از ماژولهای Wasm نوشته شده توسط مشتریان در Rust و C++ در کنار workers JavaScript پردازش میکند. موارد استفاده از احراز هویت درخواست و مسیردهی A/B تا تبدیل تصویر و بازنویسی HTML در لبه متغیر است — منطقی که در غیر این صورت به یک رفت و برگشت به یک سرور مبدأ نیاز داشت.
استنتاج هوش مصنوعی در لبه یک مورد استفاده نوظهور است که در آن قابلیت حمل Wasm و پشتیبانی wasi-nn WasmEdge تلاقی میکنند. مدلهای کوچک ONNX — طبقهبندیکنندههای تصویر، مدلهای تعبیه، دستهبندی متن — میتوانند به بستههای Wasm خودکفا کامپایل شده و بدون مدیریت وابستگی در هر گره به گرههای لبه مستقر شوند. WasmEdge از شتاب سختافزاری از طریق بکاندهای OpenVINO و TensorFlow Lite پشتیبانی میکند و تأخیر استنتاج را برای مدلهایی در محدوده زیر ۱۰۰ میلیون پارامتر در سطح رقابتی با استقرارهای بومی نگه میدارد.
ابزارهای CLI قابل حمل که به عنوان باینریهای Wasm ساخته شدهاند به صورت فایلهای تکی توزیع میشوند که بر روی هر پلتفرمی با یک زمان اجرای Wasm اجرا میشوند — بدون بیلدهای مختص معماری، بدون مشکلات لینکینگ دینامیک. پروژه wasi-vfs امکان بستهبندی یک سیستم فایل مجازی در باینری را فراهم میکند و ابزارهایی را فعال میکند که مانند اجراییهای استاتیک لینک شده رفتار میکنند اما یک بار از یک درخت منبع واحد کامپایل میشوند.
جایی که هنوز لبههای ناهموار دارد
داستان تردینگ هنوز ناقص است. پیشنهاد threads — حافظه خطی مشترک و atomics — در مرورگرهای اصلی و در Wasmtime پیادهسازی شده است، اما تعامل بین threads و مدل قابلیت WASI هنوز در حال استانداردسازی است. بیشتر استقرارهای تولیدی Wasm در خارج از مرورگرها تکرشتهای هستند، که یک محدودیت واقعی برای بارهای کاری محدود به CPU است که انتظار موازیسازی در هستهها را دارند.
بلوغ زنجیره ابزار بسته به زبان بسیار متفاوت است. Rust پشتیبانی عالی از Wasm دارد — cargo build --target wasm32-wasi برای بیشتر crateها کار میکند و اکوسیستم به خوبی آزمایش شده است. خروجی Wasm در Go در Go 1.21–1.24 بهبود یافته است اما همچنان باینریهای بزرگی تولید میکند و پشتیبانی WASI محدودی در خارج از هدف آزمایشی GOOS=wasip1 دارد. Python از طریق CPython-wasm یا Pyodide کار میکند، اما باینری مفسر به تنهایی ۲۰–۳۰ مگابایت است. زبانهای با جمعآوری زباله سربار زمان اجرا اضافه میکنند — خود GC باید در ماژول Wasm کامپایل شود، و بدون heap مدیریت شده توسط میزبان، الگوهای مصرف حافظه با استقرارهای بومی متفاوت است.
اشکالزدایی همچنان دشوار است. اطلاعات اشکالزدایی DWARF میتواند در باینریهای Wasm جاسازی شود، و ابزارهایی مانند wasm-pack و DevTools مرورگر از source maps برای Rust و C++ پشتیبانی میکنند. اما اشکالزدایی گامبهگام ماژولهای Wasm در یک زمان اجرای سرور — تنظیم نقاط شکست، بازرسی فریمهای پشته، تماشای حافظه — هنوز به نرمی اشکالزدایی کد بومی یا بایتکد JVM نیست. تجربه در حال بهبود است اما چندین سال از نظر صیقل دادن از زنجیرههای ابزار بومی عقبتر است.
سطح API WASI برای برنامههای سرور عمومی همچنان ناقص است. I/O ناهمزمان (از طریق wasi-io و wasi-http در WASI Preview 2) در دسترس است اما اکوسیستم کتابخانههایی که آن را هدف قرار میدهند نازک است. توسعهدهندگانی که کد سرور موجود را به Wasm منتقل میکنند اغلب میبینند که وابستگیهای آنها رابطهای POSIX را فرض میکند که WASI یا ارائه نمیدهد یا آنها را با اصطکاک کافی میپوشاند که نیاز به کار قابلتوجهی در پورتینگ دارد.
Wasm به کجا میرود
استانداردسازی مدل مؤلفه مهمترین توسعه کوتاهمدت است. با گسترش پذیرش WASIp2 در زمانهای اجرا — Wasmtime، WasmEdge، Wasmer و پیادهسازیهای موتور JS در مرورگرها — توانایی ترکیب مؤلفههای Wasm تایپشده از اکوسیستمهای زبانی مختلف بدون اصطکاک FFI به یک primitives واقعی پلتفرم تبدیل میشود. ابزارهای پیرامون تولید رابط WIT در پروژههای cargo-component و wit-bindgen Bytecode Alliance به سرعت در حال بلوغ هستند.
همگرایی eBPF و Wasm یک توسعه بلندمدت است که ارزش دنبال کردن دارد. هر دو فناوری اجرای کد محفظهسازی شده را در یک محیط میزبان ارائه میدهند — eBPF در کرنل لینوکس، Wasm در زمانهای اجرای فضای کاربر. پروژههایی مانند bpf-wasm استفاده از Wasm را به عنوان یک جایگزین ایمنتر و قابل حملتر برای برنامههای eBPF بومی برای مشاهدهپذیری و شبکهسازی در مجاورت کرنل بررسی میکنند. مجموعه دستورالعملها متفاوت است، اما اهداف معماری — اجرای کنترلشده توسط قابلیت، محفظهسازی شده، با عملکرد بالای کد غیرقابل اعتماد — یکسان هستند.
مرورگر هرگز قرار نبود بزرگترین سطح استقرار WebAssembly باشد. فناوری که محفظهسازی قطعی، عملکرد نزدیک به بومی و قابلیت حمل باینری واقعی در معماریها را فراهم میکند، مشکلاتی را حل میکند که در همهجای نرمافزار سیستم وجود دارد — نه فقط در زمان اجرای JavaScript. زمانهای اجرا، استانداردها و استقرارهای تولیدی واقعی اکنون به اندازهای بالغ هستند که «Wasm یک چیز مرورگر است» همان نوع خطای طبقهبندی است که «لینوکس یک سیستمعامل سرور وب است.» زمانی درست بود، و اکنون کاملاً بیربط است.