چگونه کدهای Native را در مرورگرها اجرا کنیم؟
در مرورگرها از جمله Chrome، Firefox، Edge و Safari کدها سمت کاربر تفسیر شده و توسط موتور Javascript اجرا می شوند. متاسفانه Javascript راه حل تمامی کارها از جمله تعاملات گرافیکی، امکان Video Stream و مواردی که به درجه بالایی از کارایی احتیاج دارند، نیست و اینجاست که WebAssembly وارد می شود.
WebAssembly یک نوع جدید از کد است که در مرورگرهای جدید اجرا می شود و برای افزایش کارایی برنامه ها در وب ایجاد شده است. WebAssembly بصورت فرمت سطح پایین باینری می باشد و حجم کدهای آن کم است، بنابراین سریع بارگذاری و اجرا می شود. نیازی نیست که کد باینری بنویسیم بلکه بعد از نوشتن کد با زبان سطح بالا آن را به کد باینری کامپایل می کنیم.
Assembly همان کدهای سطح پایین قابل خواندن توسط انسان است که خیلی به کد ماشین نزدیک است و کد ماشین همان اعداد دودویی است که پردازنده می فهمد.
هر زبان سطح بالا برای اجرا در پردازنده، به زبان ماشین ترجمه می شود. پردازنده های دارای معماری های مختلف نیاز به ماشین کدهای خاص خود دارند.
اما همانطور که از نام WebAssembly مشخص است، آن یک زبان Assembly نیست چون برای ماشین ها معنا ندارد و برای مروگرها است. هنگامی که کدهای WebAssembly را برای اجرا به مرورگر می دهیم دیگر نمی دانیم چه نوع ماشینی آن را اجرا خواهد کرد.
WebAssembly یک زبان برای ماشین های مفهومی است که مخرج مشترک سخت افزارهای رایج در دنیای واقعی می باشد و هنگامی که مرورگر کدهای WebAssembly را دانلود می کند، می تواند به سرعت آن را به زبان ماشین تبدیل کند. WebAssembly یک فرمت متنی دارد که نسبتا قابل خواندن است (با پسوند wat.) و یک فرمت باینری دارد که به مرورگر تحویل داده می شود (با پسوند wasm.)
WebAssembly شما را قادر می سازد که توسط زبان های C++، C و Rust برنامه بنویسید و آن را به WebAssembly Module کامپایل نمایید. سپس آن را در مروگر بارگذاری کرده و توسط Javascript فراخوانی نمایید. بنابراین WebAssembly قرار نیست جایگزین Javascript شود بلکه قرار است با آن و در کنار آن کار کند.
چرا به WebAssembly نیاز داریم؟
نرم افزارهایی مثل بازی های رایانه ای، ویرایش ویدئو، رندر سه بعدی و یا تولید موسیقی را تصور کنید. این نرم افزارها محاسبات زیادی نیاز دارند و به درجه بالایی از کارایی احتیاج دارند، کسب این نوع از کارایی از Javascript سخت است.
Javascript به عنوان یک زبان اسکریپت نویسی ساده شروع به کار کرد که با اسناد HTML در تعامل بود. هدف اصلی طراحی آن سادگی یادگیری و سادگی نوشتن آن بوده و نه سرعت. در طی سال ها مرورگرها بهبودهایی در مفسر Javascript ایجاد کرده اند تا در کارایی آن تاثیرگذار باشد.
همزمان با بهبود کارایی Javascript، لیست چیزهایی که باید در مرورگر اجرا شود گسترش یافته است. APIهای جدید نیازمندی های جدیدی را به همراه داشته اند از جمله تعاملات گرافیکی، امکان Video Stream و... که این موارد حوزه هایی هستند که Javascript به لحاظ کارایی هنوز در آنها دچار مشکل است.
بازی های رایانه ای بخصوص بخشی است که علاوه براینکه نیاز به صدا و تصویر دارد، گاهی اوقات به فیزیک و هوش مصنوعی نیز وابسته است. جرقه افزایش کارایی به منظور اجرای بازی های رایانه ای در محیط وب می تواند باب جدیدی به منظور اجرای برنامه های مختلف در محیط وب باز کند و این کار قرار است با WebAssembly انجام شود.
چرا وب تا این حد جذاب است؟
زیبایی وب این است که مثل یک جادو است و در هرجا کار می کند. احتیاجی به نصب و دانلود ندارد و با یک کلیک به چیزی که نیاز داریم، پاسخ می دهد. این قضیه امنیت بیشتری نسبت به دانلود و اجرای کدهای باینری روی سیستم را فراهم می کند به دلیل آنکه مرورگرها دارای ملزومات امنیتی قابل قبولی برای نگهداری و اجرای کدها می باشند. همچنین اشتراک گذاری در وب به راحتی دریافت اطلاعات است. وب تنها پلتفرم جهانی است که امکان دسترسی برنامه ها در هر دستگاهی را فراهم می کند.
تاکنون تعاملات وب اساسا توسط زبان Javascript انجام و پشتیبانی می شد که واقعا برای مقاصد جدیدی که به آنها اشاره شد طراحی نشده است.
WebAssembly چه چیزهایی به ارمغان می آورد؟
- سرعت (Speed)
- قابل حمل بودن (Portability)
- انعطاف پذیری (Flexibility)
سرعت WebAssembly
WebAssembly برای افزایش سرعت طراحی ارائه شده است و شامل کدهای باینری است که حجم کمتری از فایل های متنی Javascript دارد و به علت حجم کم آن، سریعتر دانلود می شود و این فاکتور مهمی در شبکه های با سرعت پایین است. همچنین سریعتر رمزگشایی و اجرا می شود.
Javascript یک زبان با Type داینامیک است، یعنی نوع متغیر در ابتدا مشخص نمی شود که موضوع باعث افزایش سرعت و سهولت در کدنویسی می شود. اما به این معنی خواهد بود که موتور Javascript کار زیادی برای انجام دارد و نیاز است که کد Parse و کامپایل شود و برای اجرا در صفحات بهینه شود. عمل Parse کد Javascript، درگیر تغییر متن ساده به یک ساختار داده است که به آن (Abstract Syntax Tree(AST گفته می شود و متن را به فرمت باینری تبدیل می کند.
اما WebAssembly کد باینری ارائه می کند و رمزگشایی آن سریعتر انجام می شود. کدهای Native نوشته شده در WebAssembly بصورت Type ایستا هستند و در زمان کامپایل نیازی نیست که مشخص شود که نوع متغیر چیست، بنابراین اغلب بهینه سازی ها در هنگام کامپایل کد صورت می گیرد، قبل از آنکه به مرورگر ارائه شود. البته اجرای فایل های باینری WASM حدود 20درصد کندتر از کد Native است.
قابل حمل بودن WebAssembly
یکی از اهداف WebAssembly قابل حمل بودن است. برای اجرای برنامه در یک دستگاه، آن برنامه باید با معماری پردازنده و سیستم عامل سازگار باشد. این قضیه به معنای آن است که کد باید به مجموعه ای از سیستم های عامل و CPUهای با معماری مختلف که می خواهیم پشتیبانی شود، کامپایل گردد. با WebAssembly یک مرحله کامپایل نیاز است و برنامه در هر مرورگر جدیدی اجرا می شود.
انعطاف پذیری WebAssembly
جالبترین مورد درباره WebAssembly انعطاف پذیری بیشتر آن در نوشتن برنامه های وب است. تاکنون مرورگرها فقط Javascript را پشتیبانی می کردند، اما با WebAssembly توسعه دهندگان می توانند از دیگر زبان ها برای توسعه و کدنویسی تحت وب استفاده کنند. Javascript هنوز هم بهترین انتخاب برای انجام بیشتر کارهاست و در صورتی که واقعا نیاز به بهبود کد نوشته شده باشد، اکنون گزینه های دیگری نیز وجود دارد. بنابراین می توان گلوگاه های موجود در کد را مجددا توسط زبان دیگری بازنویسی کرد.
WebAssembly چگونه کار می کند؟
به یک ابزار برای کامپایل کد نوشته شده به WebAssembly نیاز است. یکی از این ابزارها LLVM است که می تواند با زبان های مختلف کار کند. برای کامپایل C و ++C از یک کامپایلر مبتنی بر LLVM به نام Emscripten استفاده می شود. زبان Rust نیز دارای کامپایلر خودش به نام rustc است که می تواند مستقیما WebAssembly تولید کند.
اگر شما در زبان C کد "Hello World" را نوشته باشد، می توانید با استفاده از خط فرمان Emscripten فایل های لازم برای اجرا در مرورگر را تولید کنید. این فایل ها شامل ماژول WebAssembly به همراه فایل های JS و HTML است.
emcc hello.c -s WASM=1 -o hello.html
به HTML و JavaScript نیاز داریم، چون WebAssembly نمی تواند مستقیما به هر پلتفرمی مثل WebAudio، WebGl، Dom و... دسترسی داشته باشد و برای کار با هریک از آنها باید کد WebAssembly هر صفحه توسط JavaScript فراخوانی شود. کامپایلر Emscripten کد JS موردنیاز برای استفاده ماژول WebAssembly را ایجاد می کند. HTML فایل JS را بارگذاری می کند و JS خروجی WebAssembly را در یک Textarea یا Canvas نمایش می دهد.
می توان اینطور تصور کرد که کدهای باینری WebAssembly درواقع ماژول های یک برنامه هستند که مرورگر می تواند آنها را بازیابی، بارگذاری و اجرا کند. کدهای WebAssembly دارای Import و Export هستند که می توان با آنها مثل اشیاء Javascript رفتار کرد. همچنین می توان توابع WebAssembly را در کد Javascript فراخوانی کرد و همینطور توابع Javascript را در WebAssembly فراخوانی کرد.
می توانیم از WebAssembly استفاده کنیم؟
بله! در حال حاضر چهار مرورگر اصلی یعنی Edge، Firefox، Chrome و Safari از WebAssembly پشتیبانی می کنتد و به مرور زمان WebAssembly در تمامی مرورگرهای موبایل و Desktop پشتیبانی خواهد شد.
منابع
WebAssembly: How and why
WebAssembly support now shipping in all major browsers