什么是 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.
WebAssembly 是现代浏览器所能执行的一种新类型的代码,目标是为了在网络上获得更好的性能。
同时,它还是一种低层的二进制格式代码,体积小,因此加载和执行速度快。你不需要直接编写 WebAssembly 代码,而是从其他高级语言编译而来。WASM 被设计为其他语言的编译目标,允许服务器端代码(如C或C++代码)被编译成WASM并在浏览器中执行。
WebAssembly 标准发展
在 2015 年,WebAssembly 第一次被对外公布。
2017 年 MVP (Minimal Viable Product) 规范完成,并在 Chrome、Edge、Firefox 和 Safari 等四个主流的浏览器上得到支持。
到了 2018 年,W3C 工作组发布了三个公开的 Drafts,包含 WebAssembly 的 Core Specification、JavaScript Interface 和 Web API。
在 2019 年,WebAssembly spec 1.0 正式发布。
同年 10 月份左右,Bytecode Alliance (BA) 由 Intel、 Mozilla、Fastly、Redhat 四家公司成立,主要的目标是构建与推广基于 WebAssembly 以及 WebAssembly System Interface 的安全软件栈。
到 2021 年,BA 正式成为非盈利性的组织,微软也加入成为协作会员,到目前已经有大概 30 多家的会员,发展情况非常良好。
JavaScript 的缺点
JavaScript 是解释型语言,也是动态类型语言。如果变量类型是在运行时决定的,那么就是动态类型语言。相对于动态类型语言,还有静态类型语言,其变量类型是在定义的时候就决定了的。
对于静态语言,在编译时,通过一条指令,编译器就能知道变量的类型和内存位置。但是在JavaScript这种动态语言中,相同的操作,每次执行程序时,引擎都必须检查它是整数还是浮点数,或者任何其他有效的数据类型。所以JavaScript中的每条指令都要经过几次类型检查和转换,这会影响到它的执行速度。
JavaScript在运行代码时花费的时间:
WebAssembly花费的时间:
WebAssembly 特点
- 快速、高效、可移植:通过利用常见的硬件能力,WebAssembly 代码在不同平台上能够以接近本地速度运行。
- 可读、可调试:WebAssembly 是一门低阶语言,但是它有确实有一种人类可读的文本格式(其标准即将得到最终版本),这允许通过手工来写代码,看代码以及调试代码。
- 保持安全:WebAssembly被限制运行在一个安全的沙箱执行环境中。像其他网络代码一样,它遵循浏览器的同源策略和授权策略。
- 不破坏网络:WebAssembly的设计原则是与其他网络技术和谐共处并保持向后兼容。
WebAssembly 关键概念
- 模块:表示一个已经被浏览器编译为可执行机器码的 WebAssembly 二进制代码。一个模块是无状态的,并且像一个二进制大对象(Blob)一样能够被缓存到 IndexedDB中或者在 windows 和 workers 之间进行共享(通过postMessage() (en-US)函数)。一个模块能够像一个 ES2015 的模块一样声明导入和导出。
- 内存:ArrayBuffer,大小可变。本质上是连续的字节数组,WebAssembly 的低级内存存取指令可以对它进行读写操作。
- 表格:带类型数组,大小可变。表格中的项存储了不能作为原始字节存储在内存里的对象的引用(为了安全和可移植性的原因)。
- 实例:一个模块及其在运行时使用的所有状态,包括内存、表格和一系列导入值。
所有这些概念都是一一映射到了WebAssembly 的 JavaScript API中。
JavaScript API 为开发者提供了创建模块、内存、表格和实例的能力。给定一个 WebAssembly 实例,JavaScript 代码能够调用普通 JavaScript 函数暴露出来的导出代码。通过把 JavaScript 函数导入到 WebAssembly 实例中,任意的 JavaScript 函数都能被 WebAssembly 代码同步调用。
因为 JavaScript 能够完全控制 WebAssembly 代码如何下载、编译运行,所以,JavaScript 开发者甚至可以把 WebAssembly 想象成一个高效地生成高性能函数的 JavaScript 特性。