一、何为Wasm ?
Wasm,全称 WebAssembly,官网描述是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm被设计为一个可移植的目标,用于编译C/C++/Rust等高级语言,支持在Web上部署客户端和服务器应用程序。
Wasm 的开发者参考文档:
https://developer.mozilla.org/en-US/docs/WebAssembly
简单的来说就是使用C/C++/Rust等语言编写的代码,经过编译后得到汇编指令,再通过JavaScript相关API将文件加载到Web容器中,一句话解释就是运行在Web容器中的汇编代码。Wasm是一种可移植、体积小、加载快速的二进制格式,可以将各种编程语言的代码编译成Wasm模块,这些模块可以在现代浏览器中直接运行。尤其在涉及到GPU或CPU计算时优势相对比较明显。
二、为什么需要Wasm ?
JavaScript是解释型语言,相比于编译型语言需要在运行时转换,所以解释型语言的执行速度要慢于编译型语言。
编译型语言和解释型语言代码执行的大致流程如下:
如上流程图所示,解释型语言每次执行都需要把源码转换一次才能执行,而转换过程非常耗费时间和性能,所以在 JavaScript背景下,Web执行一些高性能应用是非常困难的,如视频剪辑、3D游戏等。
Wasm具有紧凑的二进制格式,可以接近原生的性能运行,并为C/C++等语言提供一个编译目标,以便它们可以在Web上运行。被设计为可以与JavaScript共存,允许两者一起工作。在特定的业务场景下可以完美的弥补JavaScript的缺陷。
三、优势和限制
优势:
-
性能优异:相比JavaScript代码,Wasm使用节省内存,快速加载和解释的二进制代码,具备更快执行速度,它是直接在底层虚拟机中运行的。这使得Web应用程序可以更高效地处理复杂的计算任务,例如图形渲染、物理模拟等。
-
跨平台兼容:Wasm可以在几乎所有现代浏览器中运行,兼容性可参考caniuse,无论是桌面还是移动设备。这意味着开发者可以使用各种编程语言来编写Web应用程序,而不仅仅局限于JavaScript。
-
安全性:Wasm运行在沙箱环境中,提供了良好的安全性。使用了一系列安全措施,如内存隔离和沙箱限制,以防止恶意代码对系统的攻击。
-
模块化:Wasm模块可以作为独立的组件进行开发和部署,开发者可以更好地管理和维护代码库。模块化的设计也为将来的性能优化和增量更新提供了便利。
局限性:
-
生态系统不够完善:尽管Wasm已经成为Web开发中的关键技术之一,但生态系统仍然不够完善。Wasm的工具、框架和库的数量远不如JavaScript。
-
开发门槛较高:Wasm的开发门槛相对较高。Wasm需要使用一种新的语言来编写,如C或C++等。这使得学习和使用Wasm的成本相对较高。尤其是在内存管理等方面会增加开发的复杂性。
-
与JavaScript集成问题:Wasm与JavaScript之间的集成问题是一个挑战。开发人员需要解决如何在Web应用程序中同时使用Wasm和JavaScript的问题。
-
兼容性问题:虽然现代浏览器已经开始支持Wasm,但是在一些老旧的浏览器中可能存在兼容性问题,需要开发者进行额外的处理来确保代码的兼容性。
四、Wasm工作原理
通过上述的编译型语言和解释型语言代码执行的大致流程我们可以知道Wasm是不需要被解释的,是由开发者提前编译为WebAssembly二进制格式,如下图所示。由于变量类型都是预知的,因此浏览器加载WebAssembly文件时,JavaScript引擎无须监测代码。它可以简单地将这段代码的二进制格式编译为机器码。
从这个流程中我们也可以看出,如果将每种编程语言都直接编译为机器码的各个版本,这样效率是不是更高呢?想法是好的,但实现过程确实复杂不堪的。由于浏览器是可以在若干不同的处理器 (比如手机和平板等设备) 上运行,因此为每个可能的处理器发布一个WebAssembly代码的编译后版本会很难做到。
我们可以通过替代方法即取得IR代码。IR即为中间代码(Intermediate Representation),它是编译器中很重要的一种数据结构。