WebAssembly 于 2015 年首次发布,它的第一个示例是在 Firefox、 Google Chrome 和 Microsoft Edge 浏览器中运行的 Unity 的 Angry Bots 游戏。仅仅在发布四年后,它就成为正式的 web 标准,也成为继 HTML,CSS 和 JavaScript 之后的第四种 web 语言。到目前为止,在已安装的浏览器中, 94% 都支持 WebAssembly。它可以在 web 浏览器中实现接近原生的执行速度,使得移植桌面应用(如 AutoCAD)甚至电子游戏(如《毁灭战士3》)到网页中成为了可能。
几乎每个人都在追捧 WebAssembly。接下来我们就讨论一下它吧。

JavaScript 存在什么问题?
什么是 WebAssembly?
它是类似 C, C++ 那样的编程语言吗?
WebAssembly 如何工作?
WASM 是 web 应用程序发展的未来吗?
我们会回答以上所有的问题并带你了解 Web Assembly。它有可能将我们今天所了解到的网站变得更加强大。
系紧你的安全带,我们出发啦!⚡
JavaScript 存在什么问题?

JavaScript 不是为了高性能而开发的。
1995 年,Brenden Eich 为 Netscape 浏览器设计了 JavaScript 语言。它为当时的静态 web 网页提供了新的交互方式。
JavaScript 是一种解释型和动态类型的语言。如果一种语言的变量类型是在运行时检查的,那么就称它为动态类型语言。那它存在什么问题呢?如果我们用像 C++ 这样的静态类型语言来声明一个变量,像下面这样。
int x = 5;
从以上代码中可以看出,仅仅需要一条指令,编译器就能知道 x
的类型和内存地址。但是在 JavaScript 中,同样一句表达式,JS 引擎需要在每次程序运行时检查它是整型还是浮点类型,或者是其他有效的数据类型。所以 JavaScript 中的每条指令都需要经过多次类型检查和转换,这降低了它的运行速度。
下图展示了运行代码时, JavaScript 在各个阶段所花费的时间。

下图展示的是 WebAssembly 在各个阶段所花费的时间。

和 JavaScript 相比,WebAssembly 简化了整个编译过程,使其速度更快。
JavaScript 不是为 CPU 密集型和高性能的应用程序而开发的。
什么是 WebAssembly?
浏览器只能运行 JavaScript,但是如果我们拥有一个虚拟的微处理器,可以将任何高级语言转换成机器语言运行在所有的主流浏览器上,那将会怎么样呢?这就是 web 汇编所做的事情。
下面的例子中介绍了使用 C++ 编写的 adder 函数如何被转换为 WASM。
以下是将 C++ 代码转换成浏览器可识别的二进制的虚拟处理器示意图

它是类似 C, C++ 那样的编程语言吗?

WASM 完全不是一种编程语言。
不,它并不是一种编程语言🙂。简而言之,它是一种将某种编程语言转换成浏览器可识别的机器码的技术。
“ WASM(WebAssembly 的缩写)被设计成为其他语言的编译目标,我们可以将服务端代码(如 C 或 C++)编译成 WASM,并在浏览器中执行。”

让我们来看看吧!
WebAssembly 如何工作?
要了解什么是 web 汇编,我们需要知道什么是汇编。
什么是汇编语言和汇编器呢?
- 每个处理器都有类似 x86 或者 ARM 的架构。此外,处理器只能识别机器码。
- 编写机器码是乏味的,所以我们有针对架构/处理器设计的汇编语言。
- 在汇编语言中,汇编器将指令转换成处理器可识别的机器码。
下图展示了用 C 语言编写的应用程序如何在电脑上运行。

与普通的汇编类似,WebAssembly 将 C++ 等高级语言编写的代码转换成浏览器可识别的机器码。
WebAssembly 入门
WebAssembly 是一个扩展名为 WASM 的文件。我们可以将它视为一个模块,并导入到 JavaScript 程序中。
项目目录中文件的交互 —

记住,WASM 不能直接与 DOM 交互。我们需要同时使用 JavaScript 和 WASM。
从上面的讨论中,我们了解到可以在浏览器中以接近原生的速度运行 C, C++ 等语言。为了实现它,我们需要执行以下几个步骤。🖖
1. 用你喜欢的语言编写应用程序
让我们编写一个简单的 C++ 函数来查找第 n 个斐波那契数。
// Following is a function that finds nth fibonacci written in C++
int fib(int n) {
if (n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
2. 创建一个 WASM 模块
现在,我们需要将写好的 C++ 文件转换为浏览器可识别的预编译 WASM 模块。
有很多种方法都可以将高级语言的代码转换成 WASM。在本教程中,我们将使用 Web Assembly Explorer.
第一步: 复制粘贴 C++ 代码,并点击 COMPILE 按钮
第二步: 点击 ASSEMBLE 按钮
第三步: 点击 DOWNLOAD 按钮,下载 wasm 文件


将下载的文件命名为 math.wasm
并复制到你的项目中去。
3. 分发模块 - 理想情况下,我们使用 CDN 来实现低延迟的文件分发。但是在这个示例中,我们将在本地运行 WASM 文件。
创建一个空的 script.js
文件。
你的项目目录应如下所示。

4. 加载 WASM 模块
我们将创建一个 loadWebAssembly()
函数,用来将指定文件转换为二进制数组。再将二进制数组转换为 WebAssembly 模块。必须通过 web assembly memory 来创建二进制数组。然后该模块的实例可以被浏览器读取。
你的 script.js
应该如下所示。
let math;
// Let's create a function called loadWebAssembly that converts given file into binary array buffer.
function loadWebAssembly(fileName) {
return fetch(fileName)
.then((response) => response.arrayBuffer())
.then((buffer) => WebAssembly.compile(buffer)) // Buffer converted to Web Assembly
.then((module) => {
return new WebAssembly.Instance(module);
}); // Instance of Web assmebly module is returened
}
//We call the function for math.wasm for the given Instance.
loadWebAssembly("math.wasm").then((instance) => {
...
});
5. 创建一个模块的实例。
现在到了最棘手的部分,我们需要在 JS 文件中引用 C++ 创建的函数。但是我们不能直接引用这些函数,而是需要使用 WASM 文件中生成的名称。这些名称可以在 Web Assembly Explorer 的 WAT 栏中找到。
使用下图中下划线标记的函数名。

被引用的变量都使用了下划线标记。
在你的 WAT 文件中,这些名字可能会不一样。
在
script.js
中,第一部分是描述如何加载 WASM 文件的。*第二部分创建了一些简单的 javascript 函数,用来比较 Javascript 和 WebAssembly 的性能。*🤓
//---------------------------PART 1--------------------------------------------------------
// Let's create a function called loadWebAssembly that converts given file into binary array buffer.
function loadWebAssembly(fileName) {
return fetch(fileName)
.then((response) => response.arrayBuffer())
.then((buffer) => WebAssembly.compile(buffer))
.then((module) => {
return new WebAssembly.Instance(module);
});
}
//We call the function for math.wasm
loadWebAssembly("math.wasm").then((instance) => {
fibc = instance.exports._Z3fibi;
console.log("Call your functions !");
});
//---------------------------PART 2 -----------------------------------------------
// Function written in Javascript for nth fibonacci
function fibj(n) {
if (n <= 1) return n;
return fibj(n - 1) + fibj(n - 2);
}
//This function gives the time required for C++ function
function perfoc(n) {
var startTime = performance.now();
var c = fibc(n);
var endTime = performance.now();
console.log(
`Calculating nth Fibonacci with WASM took ${
endTime - startTime
} milliseconds,nth fibonacci is ${c}`
);
}
// This function gives the time required for Javascript function
function perfoj(n) {
var startTime = performance.now();
var j = fibj(n);
var endTime = performance.now();
console.log(
`Calculating nth Fibonacci with JS took ${
endTime - startTime
} milliseconds, nth fibonacci is ${j}`
);
}
6. 调用实例的函数
现在在你的电脑上加载这个网站吧!
注意:你不能在本地直接运行 index.html,因为它不会加载 WASM 模块,除非使用 Live Server extension on Visual Studio Code 或 Xampp 在本地启动一个服务。
现在打开控制台,我们可以调用以下两个方法。
fibj()
→ 使用简单的 Javascript 编写。fibc()
→ 使用 C++ 编写 并转换为 WebAssembly。

下面是使用纯 JavaScript 编写的方法 (fibj()
) 和从 WebAssembly 导入的方法 (fibc()
) 之间的比较。
WebAssembly 非常快!
fibj()
和 fibc()
的执行时间是用下面的方法计算得出的:
perfoj()
→ 计算得出fibj()
的执行时间perfoc()
→ 计算得出fibc()
的执行时间
由上面的 GIF 动图可以看出,fibj()
(由 JavaScript 编写)的执行之间比 fibc()
(由 WebAssembly 编写)要长。
WebAssembly 是 web 应用程序发展的未来吗?
使用 web 汇编,我们可以开发以接近原生速度运行的高性能 web 应用程序。我们可以执行视频处理、3D渲染、多媒体游戏、加密计算和 AR/VR 实时应用程序等任务。
所以基本上,任何需要大量编码和性能调优的应用程序都是 WebAssembly 的完美用例。
你可以自己尝试一下使用 WebAssembly!🧑🔧
作者:浅雪2333
链接:https://juejin.cn/post/7033585275791998990
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Comments | NOTHING