WebAssembly 可移植 体积小 加载快并且兼容 Web 的全新格式 - 文章教程

WebAssembly 可移植 体积小 加载快并且兼容 Web 的全新格式

发布于 2020-02-24 字数 5480 浏览 1428 评论 0

WebAssembly/wasm WebAssembly 或者 wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式,WebAssembly 是由主流浏览器厂商组成的 W3C 社区团体 制定的一个新的规范,多个浏览器已经达成对初始 WebAssembly 版本的一致意见。

WebAssembly 可移植 体积小 加载快并且兼容 Web 的全新格式

特点

高效

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++程序

WebAssembly 可移植 体积小 加载快并且兼容 Web 的全新格式

这张图是官网上的构建流程图,构建过程中使用了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 中获取函数接口

相关链接

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

2583 文章
29 评论
84935 人气
更多

推荐作者

清欢

文章 1 评论 0

贱贱哒

文章 3 评论 0

悸初

文章 2 评论 0

西瓜杏

文章 0 评论 0

各自安好

文章 0 评论 0