WebAssembly 可移植 体积小 加载快并且兼容 Web 的全新格式
WebAssembly/wasm WebAssembly 或者 wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式,WebAssembly 是由主流浏览器厂商组成的 W3C 社区团体 制定的一个新的规范,多个浏览器已经达成对初始 WebAssembly 版本的一致意见。
特点
高效
WebAssembly 有一套完整的语义,实际上 wasm 是体积小且加载快的二进制格式, 其目标就是充分发挥硬件能力以达到原生执行效率
安全
WebAssembly 运行在一个沙箱化的执行环境中,甚至可以在现有的 JavaScript 虚拟机中实现。在web环境中,WebAssembly将会严格遵守同源策略以及浏览器安全策略。
开放
WebAssembly 设计了一个非常规整的文本格式用来、调试、测试、实验、优化、学习、教学或者编写程序。可以以这种文本格式在web页面上查看wasm模块的源码。
标准
WebAssembly 在 web 中被设计成无版本、特性可测试、向后兼容的。WebAssembly 可以被 JavaScript 调用,进入 JavaScript 上下文,也可以像 Web API 一样调用浏览器的功能。当然,WebAssembly 不仅可以运行在浏览器上,也可以运行在非web环境下。
概述
WebAssembly是一种小体积,高加载速度的二进制编码格式
从名字就能知道,这是一门底层汇编级的语言。有了 WebAssembly,我们的虚拟机层就将会同时加载和运行两种类型的代码—— JavaScript 和 WebAssembly。
这两种代码可以通过 WebAssembly 所提供的 JS API 实现互相调用。事实上,WebAssembly 代码的基本单元被称作一个模块,并且这个模块在很多方面都和 ES2015 的模块是等价的。所以我们可以认
WebAssembly 模块是一个 高性能的JS函数
WebAssembly 不是用来取代JavaScript的。它被设计为和JavaScript一起协同工作,从而使得网络开发者能够利用两种语言的优势。
WebAssembly 设计的目的不是为了手写汇编级别代码,而是为诸如C、C++等低级源语言提供一个高效的编译目标,使得以各种语言编写的代码都可以以接近原生的速度在web中运行。这一点具有重大的意义,这意味着所有由传统语言编写的客户端 app 都可以在 web 上高效运行,也就是说在未来客户端全面web化,未来可能不再需要客户端app。
同时 WebAssembly 也是一个 W3C 标准,制定过程中得到了各大浏览器厂商积极参与。各大厂商都参与到标准制定里并不常见,像js引擎,css标准,每个浏览器实际都有一套自己的标准。而获得各个厂商支持的 WebAssembly 在我看来,是未来的标准风向,会被广泛采用。
几个常见概念
Module
一个 代码单元。包含编译好的二进制代码。可以高效的缓存、共享未来可以像一个 ES2015 模块一样导入/导出。
Memory
连续的,可变大小的字节数组缓冲区。可以理解为一个 堆。
Table
连续的,可变大小的类型数组缓冲区,现在 table 只支持函数引用类型,可以类比为一个 栈。
Instance
在 Module 基础上,包含所有运行时所需状态的实例,如果把 Module 类比为一个 cpp 文件,那么 Instance 就是链接了 dll 的 exe 文件。
构建方法
直接汇编文本编写
WebAssembly 使用S-表达式作为文本格式
S 表达式用于表示一棵树。树上的每个一个节点都有一对小括号包围。括号内的第一个标签告诉你该节点的类型,其后跟随的是由空格分隔的属性或孩子节点列表劣势显而易见,编码逻辑不容易理解。
移植一个C/C++程序
这张图是官网上的构建流程图,构建过程中使用了Emscripten——一个基于llvm的编译器,目的是把 c/c++ 编译为 asm.js(js的一个真子集)
我们知道,C 和 JS 语法十分相似。所以在 C 到 JS 的编译过程中,要解决的最重要的问题主要是两点:
- C/C++是静态类型,js是动态类型
- C/C++需要程序员手动管理内存,js则有自己的一套垃圾回收机制
因此,就出现了asm.js。asm.js只有两种静态类型(i32, f64),并取消js的垃圾回收(手动管理内存)。浏览器加载到asmjs时,不进行语法分析,直接翻译为机器码执行
实际上,asm.js就是WebAssembly的一种文本格式,但不同于之前提到的s表达式。这一点类比于c,汇编语言,机器码之间的关系
由于WebAssembly当前不能直接调用Web API(如存取DOM),它只能调用JavaScript,因此需要一段js胶水代码使WebAssembly能够调用到Web API
移植代码缺点在于需要较复杂的依赖,相比之下,汇编编写依赖都由程序员自己定义
使用方法
WebAssembly的模块在很大程度上和ES2015模块类似。在使用上也是分为两步:加载和调用
加载
- 获取.wasm二进制模块文件
- 编译为Module
- 实例化为Instance,由于获取,编译和实例化都是异步的,所以实际使用中为了方便,可以直接构建一个异步的 loader 对 wasm 进行加载
调用
从 Instance 中获取函数接口
相关链接
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论