WebAssembly 入门
2023-09-19
这是一篇简单介绍 WebAssembly 的文章。文章里不会涉及太多关于底层实现的细节,因为我也是刚开始接触这个领域。
文章将主要分为三个部分:
- WebAssembly 是什么
- 被设计用来解决什么问题
- 如何有效地使用
素材来源不仅限于官方文档,还有 YouTube 上一些精彩的分享。这些都将列在尾部的参考中。
1. WebAssembly 是什么
按照 官网🔗 官网说法,
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.
首先,它是个二进制指令格式,其次是基于栈的虚拟机,同时为多种不同编程语言生成可移植目标,并且可以在客户端和服务端上部署。
初衷就是为了统筹 Native 的效率和 Web 的通用性。
特性主要有四个:
- 性能和速度
- 安全
- 开放和可调试
- 开放 Web 平台组件
简而言之,WebAssembly 是为了将一些 Native 端才有的能力,比如已有的库,高性能应用等,移植到 Web 端。
试想,如果未来所有的原生应用都消失,用户所有需求都可以借助一个浏览器满足。那么浏览器即是下一代的操作系统,此言非虚。
2. WebAssembly 的发展史
任何技术都不是无缘无故发生。
WebAssembly 的诞生,本是为了解决 JavaScript 既有的一些问题。
V8 引擎在 2008 年的时候被首次引入到 Chrome,利用即时编译(Just-in-time Compilation, JIT)等技术,极大提高了 JavaScript 这门脚本语言的执行效率。
但人的野心无限。
有人就想,能不能让 JavaScript 以一种类似 Native code 的效率运行?
于是 Native Client (NaCI)🔗 Native Client (NaCI)技术于 2008 年被 Google 的 Brad Chen, Bennet Yee 和 David Sehr 提出。后来为了移植性,又搞出了 Portable Native Client (PNaCI)。
基本的原理可见下图,由于 NaCI 本身就是个比较复杂的技术,这里不展开。
简单来说,NaCI 有自己的 runtime,运行在独立的进程中,通过一系列接口和外界交互。
asm.js和Emscripten则是走了另外一条路。
直接将 C++ 等 Native 语言,编译成 JavaScript。其中,asm.js 是一种低级的 JavaScript 子集,目标是提高运行效率;Emscripten 是一个工具链,将 C/C++ 等代码编译成 asm.js。
据当时的测试,性能提升明显。
看起来已经很好了,但是还不够。
因为首先,相比于紧凑的二进制格式,asm.js 需要解析,解析就需要耗费时间,因此 asm.js 存在冷启动的问题;另外,asm.js 仍然是一个比较 hack 的解决方案,只能解决部分问题。
于是在 2015 年,WebAssembly 诞生。
结合了 NaCI 和 asm.js 两者的优点。
一方面,它很像 NaCI,不是基于 JavaScript,而是一个全新的、经过正确设计、同时以二进制编码的指令集合。
另一方面,它又很像 asm.js,运行在 Render 进程里。
工具链主要有两个:
- Emscripten,但是编译产出结果是 WebAssembly,而不是 asm.js
- 一个新的 LLVM WebAssembly 后端,可以这么理解,LLVM 将所有的语言都编译成一个中间语言(LLVM IR),后端需要做的,就是将 LLVM IR 转换成另一门语言,这里是 WebAssembly
尽管 WebAssembly 诞生还不到 10 年,仍然在发展,但最新的浏览器已经支持了很多新特性。
3. 如何开始
先看一个简单的例子。
假如我们有一个用 C/C++ 写的模块,经过一系列处理,就可以实现在浏览器中调用。
测试用的是 Ubuntu 系统。
先安装emcc
环境。
hello.cc
内容为:
使用emcc
编译:
也可以:
其中:
wasm
是二进制的 Wasm 模块js
是一个包含胶水层的 JavaScript 文件,将原生的函数翻译成 js 函数html
可理解为一个测试用网页,实例化 Wasm 代码,然后展示结果
4. 总结
本文只是简单介绍了 WebAssembly 技术产生的背景,以及发展过程,最后提供了一个简单的 example 供测试。
从某些方面看,WebAssembly 并没有什么黑魔法,它只是将代码以一种更容易被优化的方式呈现,峰值的性能和原始 JavaScript 差异不大,只是 WebAssembly 平均效率会高一些。
(完)
参考
- 本文作者:Plantree
- 本文链接:https://plantree.me/blog/2023/introduction-to-webassembly/
- 版权声明:所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
最后更新于: 2024-11-20T09:44:17+08:00