0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

WebAssembly是什么?为什么需要WebAssembly?WebAssembly的工作原理

OSC开源社区 来源:OSCHINA 社区 2023-08-01 15:48 次阅读

来源 | OSCHINA 社区

作者 | 京东云开发者-京东物流 潘维高

1 WebAssembly 是什么?

一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果

W3C WebAssembly Community Group 开发的一项网络标准,对于浏览器而言,WebAssembly 提供了一条途径,让各种语言编写的代码以接近原生的速度在 Web 中运行。在这种情况下,以前无法以此方式运行的客户端软件等都将可以运行在 Web 中。

WebAssembly 设计之初就决定和 JavaScript 一起协同运行 —— 通过 JavaScript 中的 WebAssembly API,可以把 WebAssembly 模块加载到一个 JavaScript 应用中并且在两者之间互相调用。这样可以在同一个应用中使用 WebAssembly 的高性能及 JavaScript 的高灵活性。

2 为什么需要 WebAssembly?

众所周知 JavaScript 是解释型语言,相比于编译型语言需要在运行时转换,所以解释型语言的执行速度要慢于编译型语言。

编译型语言和解释型语言代码执行的具体流程如下:

wKgZomTIuOOAUwXDAAE6NrA09Vs673.png

因为解释型语言每次执行都需要把源码转换一次才能执行,而转换过程非常耗费时间和性能,也就导致在 JavaScript 背景下,web 无法执行一些高性能应用,如图片剪辑、视频剪辑、3D 游戏等。

根据 MDN 的定义,WebAssembly 是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如 C / C ++ 等语言提供一个编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 JavaScript 共存,允许两者一起工作。

3 WebAssembly 的工作原理

WebAssembly 不被解释,而是由开发者提前编译为 WebAssembly 二进制格式,如下图所示。由于变量类型都是预知的,因此浏览器加载 WebAssembly 文件时,JavaScript 引擎无须监测代码。它可以简单地将这段代码的二进制格式编译为机器码。

wKgZomTIuOOAAmVfAACXSP8olNU342.png

如果将每种编程语言都直接编译为机器码的各个版本,那么效率会很低。编译器中称为前端的部分会将所编写的代码编译为一种中间表示 (intermediate representation,IR)。创建好 IR 代码后,编译器的后端部分会接收 IR 代码,对其进行优化,然后将其转换为所需要的机器码。

wKgaomTIuOOAItJCAAA-nBKrYiI343.png

由于浏览器可以在若干不同的处理器 (比如桌面计算机、智能手机和平板设备) 上运行,因此为每个可能的处理器发布一个 WebAssembly 代码的编译后版本会非常繁复。替代方法即取得 IR 代码,并通过一个专门的编译器来运行,这个编译器将 IR 代码转换为一种专用字节码并放入后缀为.wasm 的文件中。此时 wasm 文件中的字节码还不是机器码,它只是支持 WebAssembly 的浏览器能够理解的一组虚拟指令。当加载到支持 WebAssembly 的浏览器中时,浏览器会验证这个文件的合法性,然后这些字节码会继续编译为浏览器所运行的设备上的机器码。如下图

wKgaomTIuOOAItJCAAA-nBKrYiI343.png

wKgZomTIuOOACvY6AAArSHYBBew020.png

WebAssembly 被设计为 JavaScript 的一个组件,不是它的替代品。虽然有些开发者试图只用 WebAssembly 来创建整个网站,但这不是普遍情况。一般情况 JavaScript 仍然是更好的选择。

4 WebAssembly 模块内部

wKgaomTIuOOAI_8nAAI-AaL9QGY529.png

模块中不同段的含义说明:

wKgaomTIuOSASD4MAADJL6BYrDE904.pngwKgZomTIuOSAYuExAAAnt2q8_Bo497.png

编译器负责生成 WebAssembly 模块的段,并将它们按照适当顺序放置。

所有的段都是可选的,因此可能存在空模块。

如果指定了已知段,那么它们只能出现一次并且要按照特定顺序出现。

自定义段可以放置在已知段之前、之间或之后,用于指定不适用已知段的数据。

5 哪些语言可用来创建 WebAssembly 模块?

现在 WebAssembly 的最小可行性版本(Minimum Viable Product,MVP)还没有垃圾回收(garbage collection,GC),他限制了一些语言的使用。GC 作为一种后 MVP 功能正在开发中,实现之前,有几种语言正在试验 WebAssembly 支持,方式是将自己的 VM 编译到 WebAssembly,或者在某些情况下将自己的垃圾回收器包含进去。

以下语言正在试验或已经完成 WebAssembly 支持:

C 和 C++

Rust 正致力于成为 WebAssembly 的首选编程语言。

AssemblyScript 是一种新编译器,它用来将 TypeScript 转换为 WebAssembly。

TeaVM 是一个将 Java 转译到 JavaScript 的工具,现在也可以生成 WebAssembly 了。

Go 1.11 为 WebAssembly 增加了一个试验性项目,其编译后的 WebAssembly 模块包含一个垃圾回收器。

Pyodide 是 Python 的一个项目,其中包含了 Python 科学栈的核心包:Numpy、Pandas 和 matplotlib。

Blazor 是微软的实验性项目,用于将 C# 引入 WebAssembly。

更多列表关注 github: WebAssembly 支持列表

相关案例:

TeaVM:它可以将 JVM 字节码翻译成 JavaScript 和 WebAssembly

我们有一段时间后端开始做一些前端开发,但是结果有时并不尽如人意,关键就在于我们的后端开发人员对前端无论是框架还是语法还是规范,都不是非常了解。这是在所难免的,但是因为业务需要又不得不做。

TeaVM 就为我们这种情况提供了一种解决方案,我们的后端开发人员依然使用自己熟悉的语言(java)进行开发。功能开发完成后再将_.class 或_.jar 文件通过 TeaVM 编译成 wasm 或 JavaScript 供浏览器加载调用。

git:https://github.com/konsoletyper/teavm

官网:https://teavm.org/

6 WebAssembly 可以用在哪?

目前大多数浏览器厂商都已经支持 WebAssembly,包括 Chrome、Edge、Firefox 和 Safari。移动端 Web 浏览器也同样支持。Node.js 也从版本 8 开始支持。

WebAssembly 不是 JavaScript 的替代品,而是它的一个补充,有些情况下 WebAssembly 是更好的选择,有些情况下使用 JavaScript 会是一个更优的方案。与 JavaScript 在同一个 VM 运行可让两种技术相辅相成。

WebAssembly 为非 JavaScript 的开发者提供了一个新的道路,帮助他们在 web 中使用自己编写的代码。也让不了解 C 或 C++ 等语言的 web 开发者可与访问更新、更快的库。个人理解 WebAssembly 也可用来优化某些库的执行速度。

6.1 一些使用 webAssembly 的案例

Figma — 基于浏览器的多人实时协作 UI 设计工具:https://www.figma.com/

Google Earth https://earth.google.com/ - 17 年开始支持在 FireFox 打开,主要依赖 webAssembly。之前使用 Native Client 导致只能在 chrome 中运行

Magnum — 跨平台的 OpenGL 图形引擎 https://github.com/mosra/magnum

Egret Engine - 一款 HTML5 游戏引擎 https://github.com/egret-labs/egret-core/

Web-DSP — 使用浏览器就能即时制作多媒体影音特效 https://github.com/shamadee/web-dsp

7 WebAssembly 怎么用?

7.1 得到 wasm 文件手动引入

var importObject = {
  imports: {
      imported_func: function(arg) {
        console.log(arg);
      }
    }
  };
  // 输出 42
  fetch('simple.wasm')
  .then(res =>
    res.arrayBuffer()
  ).then(bytes =>
    WebAssembly.instantiate(bytes, importObject)
  ).then(results => {
    results.instance.exports.exported_func();
  });





cc6ff9bc-2f93-11ee-9e74-dac502259ad0.png




cc90d862-2f93-11ee-9e74-dac502259ad0.png




7.2 得到编译好的 npm 包引入执行


// alert(`Hello, ${name}`)
const js = import("./node_modules/@jdl/hello-wasm/hello_wasm.js");
js.then(js => {
  js.greet("WebAssembly");
});


cc9d597a-2f93-11ee-9e74-dac502259ad0.png

以下为 hello_wasm.js 文件编译前源码
// rust
extern crate wasm_bindgen;

use wasm_bindgen::*;

#[wasm_bindgen]
extern {
    pub fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}


本文从为什么需要 WebAssembly、WebAssembly 的工作原理、哪些语言可用来创建 WebAssembly 模块、WebAssembly 可以用在哪里 以及 怎么使用 几方面简要介绍了 webAssembly。如果之前没有了解过 webAssembly,可以做一些简要的了解。


审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Web
    Web
    +关注

    关注

    2

    文章

    1238

    浏览量

    68459
  • 浏览器
    +关注

    关注

    1

    文章

    974

    浏览量

    34418
  • C++
    C++
    +关注

    关注

    21

    文章

    2066

    浏览量

    72900
  • 代码
    +关注

    关注

    30

    文章

    4555

    浏览量

    66771
  • javascript
    +关注

    关注

    0

    文章

    511

    浏览量

    53403

原文标题:初探webAssembly

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    WebAssembly技术_编译ffmpeg(ubuntu20.04)

    WebAssembly并不是直接用汇编语言,而提供了抓换机制(LLVM IR),把高级别的语言(C,C++和Rust)编译为WebAssembly,以便有机会在浏览器中运行。主要是解决目前JS语言的效率问题,设计立足点为快速,内存安全和开放。所以是一种运行机制,一种新的字
    的头像 发表于 07-14 10:29 1647次阅读
    <b class='flag-5'>WebAssembly</b>技术_编译ffmpeg(ubuntu20.04)

    WebAssembly的起源及实践分析

    在浏览器之争中,Chrome凭借Java的卓越性能取得了市场主导地位,然而由于Java的无类型特性,导致其运行时消耗大量的性能做为代价,这也是Java的瓶颈之一。WebAssembly旨在解决这一
    发表于 09-30 14:18 0次下载
    <b class='flag-5'>WebAssembly</b>的起源及实践分析

    关于Mozilla让WebAssembly并行启动

    Mozilla通过在Firefox浏览器中使用并行提高了WebAssembly字节码和asm.js的Java子集的性能。 Mozilla的工程师通过使用并行来减少浏览器中asm.js程序启动的时间
    发表于 10-10 17:32 5次下载
    关于Mozilla让<b class='flag-5'>WebAssembly</b>并行启动

    .NET应用程序可以直接调用WebAssembly模块了

    WebAssembly Runtime现已添加.NET Core API,开发者可直接在.NET应用程序中调用WebAssembly模块。
    的头像 发表于 12-10 11:35 2219次阅读

    使用WebAssembly的网站大都用于加密货币挖掘和在线游戏

    WebAssembly 由 Mozilla、谷歌、微软和苹果这四个主要的浏览器供应商协同创建,它引入了一种新的二进制文件格式,用于将代码从 Web 服务器传输到浏览器。
    的头像 发表于 01-10 16:00 1867次阅读
    使用<b class='flag-5'>WebAssembly</b>的网站大都用于加密货币挖掘和在线游戏

    WebAssembly中的BL602/BL604模拟器使用

    让我们使用WebAssembly在 Web 浏览器中模拟 BL602 / BL604 Rust 固件
    发表于 03-18 10:11 2次下载

    WebAssembly技术_编译ffmpeg(ubuntu)

    WebAssembly/wasm WebAssembly 或者 wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式。
    的头像 发表于 08-14 09:43 1286次阅读
    <b class='flag-5'>WebAssembly</b>技术_编译ffmpeg(ubuntu)

    WebAssembly_Web运行CC++程序(win10)

    WebAssembly是2015年诞生的一项新的技术,在2015年7月,Wasm首次对外公开,并正式开始设计,同年,W3C成立了Wasm社区小组(成员包括Chrome、Edge、Firefox和WebKit),致力于推动Wasm技术的早期发展。
    的头像 发表于 08-14 09:44 1491次阅读

    介绍WebAssembly现存的一些风险和他们的应对方法

    Wasmtime的一个常见用例是同时并发运行许多不同的 WebAssembly guests,并在它们之间设置时间片。Wasmtime内置支持在一个异步事件循环上运行对Wasm的调用。
    的头像 发表于 09-21 09:30 973次阅读

    浅析Wasm-bpf架起Webassembly和eBPF内核可编程的桥梁

    Wasm 最初是以浏览器安全沙盒为目的开发的,发展到目前为止,WebAssembly 已经成为一个用于云原生软件组件的高性能、跨平台和多语言软件沙箱环境
    的头像 发表于 02-13 11:40 492次阅读

    WebAssembly中使用Rust编写eBPF程序并发布OCI镜像

    WebAssembly(Wasm)最初是以浏览器安全沙盒为目的开发的,发展到目前为止,WebAssembly 已经成为一个用于云原生软件组件的高性能、跨平台和多语言软件沙箱环境,Wasm 轻量级容器也非常适合作为下一代无服务器平台运行时,或在边缘计算等资源受限的场景高效执
    的头像 发表于 02-14 18:10 907次阅读

    重新构想前端开发!Kotlin推出新功能

    2021 年,WebAssembly 开源项目开始支持 GC(垃圾回收器),为实现 WebAssembly 支持像 Java、Kotlin 这样的前端语言做准备。同年,Kotlin 程序语言开发团队更新了发展路线,其中的一个重点就是增加
    的头像 发表于 02-23 09:58 1594次阅读

    使用C++编写通用库并在 Rust 中使用它 (WASI)

    使用 C++ 编写通用库并在 Rust 中使用它 (WASI) WebAssembly 简介 WebAssembly 是一种二进制指令格式,旨在成为一种低级虚拟机,可以在 Web 浏览器中以接近本机
    的头像 发表于 06-16 10:03 650次阅读
    使用C++编写通用库并在 Rust 中使用它 (WASI)

    基于WebAssembly构建Web端音视频通话引擎

    Web技术在发展,音视频通话需求在演进,怎么去实现新的Web技术点在实际应用中的值,以及给我们带来更大的收益是需要我们去探索和实践的。LiveVideoStackCon 2022北京站邀请到田建华
    的头像 发表于 06-26 15:56 482次阅读
    基于<b class='flag-5'>WebAssembly</b>构建Web端音视频通话引擎

    Chrome支持运行Kotlin、Java等GC编程语言

    谷歌 Chrome 开发者博客官宣:Chrome 已默认启用 WebAssembly 垃圾回收 (WasmGC) 功能 —— 能够将具有 GC 的编程语言编译为 WebAssembly (Wasm)。
    的头像 发表于 11-24 11:43 389次阅读