一文搞懂WebAssembly技术

377 阅读3分钟

这是我参与 8 月更文挑战的第 31 天,活动详情查看: 8月更文挑战

前言

今天我们来聊聊WebAssembly,WebAssembly 是一项相对较新的技术,W3C 于 2018 年发布了最终规范草案。它最初被设想为一种新的运行时,具有多语言支持,可在浏览器中提供接近本机的执行速度,并且确实实现了这一点承诺。那么,什么是WebAssembly呢?

WebAssembly 是在浏览器端可执行的字节码,主要解决的问题是性能。编辑器能把 C、C++、Go、TS 等语言编译成 WebAssembly 并能在浏览器中运行。

一般来说,使用WebAssembly的场景对性能有很高要求,另外也可以把一些本来需要在后端完成的操作放到前端来做。比如视频解码、图片处理等等。

Javascript

首先,Javascript是一门解释性的语言,在为数不多JavaScript引擎中,V8无疑是最流行的,Chrome与Node.js都使用了V8引擎,Chrome的市场占有率高达60%,而Node.js是JS后端编程的事实标准。国内的众多浏览器,其实都是基于Chromium浏览器开发,而Chromium相当于开源版本的Chrome,自然也是基于V8引擎的。神奇的是,就连浏览器界的独树一帜的Microsoft也投靠了Chromium阵营。另外,Electron是基于Node.js与Chromium开发桌面应用,也是基于V8的。

JavaScript是一门动态类型语言,这会给编译器增加很大难度,因此专家们觉得它的性能很难提高,但是V8居然做到了,生成了非常高效的machine code(其实是汇编代码),这使得JS可以应用在各个领域,比如Web、APP、桌面端、服务端以及IOT。

严格来讲,V8所生成的代码是汇编代码而非机器代码,但是V8相关的文档、博客以及其他资料都把V8生成的代码称作machine code。汇编代码与机器代码很多是一一对应的,也很容易互相转换,这也是反编译的原理,因此他们把V8生成的代码称为Machine Code也未尝不可,但是并不严谨。在运行C、C++以及Java等程序之前,需要进行编译,不能直接执行源码;但对于JavaScript来说,我们可以直接执行源码(比如:node server.js),它是在运行的时候先编译再执行,这种方式被称为即时编译(Just-in-time compilation),简称为JIT。因此,V8也属于JIT编译器。

WebAssembly的设计初衷

  1. WASM的出现绝不是要让它成为一门新的编程语言,正相反,它被规划并设计为一个编译目标,允许C的开发者编译其代码,并在浏览器上运行。
  2. WASM旨在提供高度优化的网络计算能力,并被期待去打破JavaScript在既有环境中的垄断(尽管JavaScript是一种很不错的语言,但其在设计之初就没有考虑到性能上的问题)。
  3. WASM并不是被拿来实现网站优化的,而是尝试在运行以下这些繁重任务时,将浏览器(以及服务端运行时,例如Node.js)的运行推升到一个水准:
    • 视频编辑
    • 游戏开发
    • AR / VR实时应用
    • 音乐编辑和流媒体
    • 加密
    • VPN
    • 影像辨识
    • ...

WebAssembly是如何工作的

WebAssembly 使用基于栈的虚拟机,但是并不是说在实际的物理机器上它就是这么生效的。当浏览器翻译 WebAssembly 到机器码时,浏览器会使用寄存器,而 WebAssembly 代码并不指定用哪些寄存器,这样做的好处是给浏览器最大的自由度,让其自己来进行寄存器的最佳分配。

小结

WebAssembly的出现,让我们在浏览器中开发不再受制于语言,也不再受制于Javascript的执行效率。

利用WebAssembly可以使用客户端的计算能力,从而降低服务器资源的使用率。