WebAssembly初探

  • Post author:
  • Post category:其他



引言

WebAssembly (简称 Wasm) 是目前备受关注的一门新的计算机语言,21年W3C也宣布WebAssembly成为web的第四种官方语言,本文将对 WebAssembly 的发展,目标,优势等内容展开介绍。

WebAssembly 标准演进史

  • 2013年Asm.js 被移植到浏览器中,这是 WASM 的前身

  • 在 2015 年,WebAssembly 首次公开公布,彼时各大浏览器厂商开始合作开发 WASM,且成立 W3C(WebAssembly Community Group),此时雏形已现

  • 2017 年 WebAseembly MVP (Minimal Viable Product) 规范完成, Chrome、Edge、Firefox 和 Safari 等四个主流的浏览器上开始支持。

  • 2018 年,W3C 工作组发布了三个公开的 草案,包含 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 多家的会员,发展情况非常良好。

  • 2022年,发布了 2.0 的草案。


WebAssembly 是什么?

是 W3C 制定的一个新的规范,是一个高效、安全且兼容 Web 的全新格式,并于2019/12/05成为W3C的标准。

  • 高效:WASM 有一套完整的语言特性,实际上 WASM 是体积小且加载快的二进制格式, 其目标就是充分发挥硬件的能力以达到原生语言的执行效率

  • 安全:WASM 运行在一个内存安全,沙箱化的执行环境中,甚至可以在现有的 JavaScript 虚拟机中实现。在 Web 环境中 ,WASM 将会严格遵守同源策略以及浏览器安全策略

  • 标准:WASM 在 Web 中被设计成无版本、特性可测试、向后兼容的。WASM 可以被 JavaScript 调用,进入 JavaScript 上下文,也可以像 Web API 一样调用浏览器的功能。WASM 不仅可以运行在浏览器上,也可以运行在非 Web 环境下(如 Node.js、Deno、物联网设备等。


WebAssembly 社区的发展态势如何?

兼容性:可以看到目前的主流浏览器:Chrome、Edge、Safari、Firefox、Opera 都已经支持,Safari 11版本(对应 IOS 11)以上的移动端对于 WASM 的支持也比较好了,如果是低于 IOS 11 以下的系统就需要做逻辑兜底的处理了。所以如果是 B 端的项目,可以放心大胆的去在项目中进行落地,如果是 C 端的项目,可能会有一小部分用户的系统会不支持,这时候可以使用 wasm2js 工具来做代码转换兜底。


WebAssembly低成本集成

由于WebAssembly的标准化,官方制定了标准的中间指令格式,开发者可以使用多种不同的开发语言,如 C/C++,Java/Kotlin, TypeScript, Rust 等,利用工具链可以转化为统一的 WebAssembly 的中间指令格式,以便于开发者低成本地接入或在现有的项目中集成。

传统开发模式基本的流程是首先通过特定的语言生态开发、通过平台相关的工具链发布,在特定的系统环境中运行应用。这种模式在大型系统中不可避免的暴露出其劣势,跨平台优势能抹去一些不必要的开销:

  • 首先,开发成本高,为了满足项目中不同需求,需要采用特定的语言来开发,开发者需要掌握多种不同类型的语言,技术栈负担重。

  • 其次,大型软件需要解决不同开发语言的协作问题(交互和集成),不同语言间交互需要FFI支持,交互过程中不可避免的性能损耗。

  • 再次,不同语言开发的应用发布工具链都是独有的,对安全性,隔离性,跨平台等方面都会各自面临相同的问题,会增加重复的消耗。

  • 最后,不同的语言是为解决特定的问题,会在其他方面做妥协(例如,脚本语言 JavaScript, Ruby 开发者门槛低,但性能也低),对于已有模块的复用和迁移代价较大。

WebAssembly 作为一个可安全隔离,高效,跨平台,多语言支持的可移植中间二进制格式,为解决上述问题提供了可实施的路径,不同的开发者可以利用 WebAssembly 的特性来满足业务需求。

对于 JS、Python 等脚本语言来说,为了追求更高的性能,可以将性能热点模块通过 WebAssembly 来实现,从而获取高性能执行的收益。对于 Rust 开发者来说,利用语言的特性可以获取高性能和高安全性,但为了让开发者获得更低的开发门槛,可以编译为 WebAssembly 模块提供给类似 JavaScript、Python 等脚本语言使用,降低开发者门槛;对于 C++ 开发者来说,可以获得高性能,但 C++ 不完备的安全性机制可能会使应用存在安全隐患,可以将其编译为 WebAssembly 在轻量级安全沙箱中运行,从而使得安全机制做到开箱即用(安全性保障需要安全领域的专业支持,门槛很高)。


WebAssembly开发工具


AssemblyScript,

支持直接将TypeScript编译成WebAssembly。这对于很多前端同学来说,入门的门槛还是很低的。


Emscripten

,可以说是WebAssembly的灵魂工具都不为过,上面说了很多编译,这个就是那个编译器。将其他的高级语言,编译成WebAssembly。


WebAssembly体验

环境配置:需要科学上网

# 下载Emscripten源码git clone https://github.com/juj/emsdk.gitcd emsdk
# 安装最新版本./emsdk install latest
# 使用最新版本./emsdk activate latest
# 添加环境变量source ./emsdk_env.sh

demo文件

int number(uint32_t n) {        int ret = 0;        for (int i = 0; i < 32; i++) {            if (n & (1 << i)) {                ret++;            }        }        printf("Hello World!"+ret);        return ret;    }

编译

emcc number.c -o index.html

目录结构

最后运行一个本地的服务器打开html文件,即可看到运行结果。


最后

本文只是讲了WebAssembly的冰山一角,作为WebAssembly的开篇带大家简单了解了WebAssembly的诞生,标准演进史,但像WebAssembly接近native的能力,语言特性,未来的标准及落地场景都还有很多没有涉及,后续有机会的话也会继续更新。WebAssembly对于web开发人员在某些方面,比如复杂计算,图形渲染方面是个锦上添花的技术,但也要注意使用方式,不当的调用有可能会抵消技术本身带来的性能红利。更多的是WebAssembly给非web开发人员,对于进入web世界开了一扇窗,让其他语言的代码能高性能的运行在web中,我认为这是它目前最大的价值。

欢迎关注,感谢支持,同时也欢迎关注:

江湖修行公众号

,文章首发。



版权声明:本文为jh1988abc原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。