初探webAssembly

2023-11-04

1 WebAssembly是什么?

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

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

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

2 为什么需要WebAssembly?

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

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

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

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

3 WebAssembly的工作原理

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

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

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

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

4 WebAssembly模块内部

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

编译器负责生成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();
  });

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

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

以下为hello_wasm.js文件编译前源码

// rust
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[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,可以做一些简要的了解。

参考文献

《WebAssembly 实战》 —- C. 杰勒德·加伦特

编译 Rust 为 WebAssembly - WebAssembly | MDN

作者:京东物流 潘维高

来源:京东云开发者社区 自猿其说Tech

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

初探webAssembly 的相关文章

随机推荐

  • UE4 UPROPERTY属性修饰符用bool变量控制变量是否可编辑

    meta EditCondition bool变量 UPROPERTY EditAnyWhere BlueprintReadWrite Category UPROPERTY Test bool A UPROPERTY EditAnyWher
  • 【Angular2】模板语法之 ngModel

    NgModel实现双向绑定及其实现原理 讨论 ngModel 之前 先讲下属性绑定和事件绑定 在属性绑定中 值从模型中流动到视图上的目标属性 通过把属性名放在方括号中来标记出目标属性 这是从模型到视图的单向数据绑定 在事件绑定中 值从视图上
  • 51单片机学习笔记(七) -蜂鸣器

    文章目录 一 蜂鸣器的概念 1 分类 2 工作原理 3 原理图 二 让蜂鸣器响起来 三 用定时器控制蜂鸣器音调 四 蜂鸣器发出滴滴声 总结 一 蜂鸣器的概念 1 分类 1 无源蜂鸣器 必须方波信号驱动才能发声 2 有缘蜂鸣器 给高电平驱动即
  • VMware虚拟机网络连接设置——仅主机模式(Windows版)

    VMware虚拟机网络连接设置 仅主机模式 Windows版 前言 各位看官 小二已多次测试教程的实用性及准确性 请按目录顺序放心食用 一 设置VMware的虚拟网络 1 1 打开虚拟网络编辑器 在VMware软件窗口工具栏选择 编辑 gt
  • 【Spring Security】入门——实现用户注册登录

    一 项目框架 1 项目结构 2 选择安装依赖 二 数据库 三 代码实现 实现思路 1 配置文件 2 编写测试页面 login jsp register jsp menu jsp 3 配置视图控制器 4 进行Spring Security配置
  • Vim的使用:常用键位总结

    目录 1 普通模式 1 1 光标移动 1 2 搜索替换 1 3 删除 复制 粘贴 1 4 注释 取消注释 1 4 1 注释 1 4 2 取消注释 2 插入模式 3 命令模式 进入vim的方式很简单 比如说现在要用vim打开test cpp
  • 给两个四元数,如何生成一个四元数轨迹,让四元数转化成的旋转矩阵轨迹可微

    假设给定两个四元数 q1 和 q2 它们定义了从初始位置到结束位置的旋转 要生成四元数轨迹 可以考虑使用四元数球面线性插值 SLERP 具体步骤如下 1 标准化 q1 和 q2 确保它们都是单位四元数 2 计算 q1 和 q2 之间的夹角
  • 嵌入式系统之cyber-physical system

    嵌入式系统在生活中随处可见 之前的嵌入式做法一般都是在一些现成的板子上移植linux做一些剪切加一些传感器写一些设备驱动 都是随着时代的发展 嵌入式不再是之前大家认为的那种单片机原理 其实现在很多人都把搞单片机弄的那一套认为是嵌入式 当然业
  • ViewPager两种方式实现无限轮播

    给自己的忠告 虽然轮子很好用 但是使用轮子的前提是 如果不去封装一些复杂的功能 自己会用最基本的方法写一个 不然再好的轮子那也是别人的 当自己项目遇到和轮子不一样的地方 那就只能束手无策或者改人家的源码 当然能看懂轮子的封装思想自己学以致用
  • 为什么超过500万开发者选择了ASP.NET Core?

    目录 一 What ASP NET Core 二 Why ASP NET Core 三 为什么选择这项技术 四 ASP NET Core的优势具体可以梳理为以下几个方面 1 生成Web UI 和Web API的统一场景 2 Blazor 3
  • XX系统部署结构图

  • leetcode 26. 删除有序数组中的重复项

    给你一个 升序排列 的数组 nums 请你 原地 删除重复出现的元素 使每个元素 只出现一次 返回删除后数组的新长度 元素的 相对顺序 应该保持 一致 然后返回 nums 中唯一元素的个数 考虑 nums 的唯一元素的数量为 k 你需要做以
  • 扫码支付自动跳转(以上传一个压缩包到某种网盘或者可以下载的地址等让人付费解压为例)

    1 你有一个比较有用的资源A zip文件 2 做一个很简单的首页网页B并命名为解压码 html文件
  • FasterViT:基于分层注意力的快速视觉transformer

    文章目录 摘要 1 简介 2 相关工作 3 FasterViT 3 1 设计主体 3 2 架构设计 3 3 FasterViT组件 4 实验 4 1 训练设置 5 结果 5 1 图像分类 5 2 目标检测与实例分割 5 3 语义分割 6 消
  • Vue组件的边界情况

    01 root 访问组件的根实例 用的不多 基本上在vuex上进行数据操作 02 parent children 可以获得父组件或者子组件上边的数据 一般不建议使用 parent 因为如果获取这个值进行修改的话 也会更改父组件上边的数据
  • 图片颜色切换实现按钮控制暂停和开始

  • BES(恒玄) 提示音解析

    今天 继续讲解BES平台 UI 最后模块 提示音 提示音这一块比较繁琐 也很容易出问题 我们就 提示音实现机制 问题点 做个全面的讲解 BES 提示音分为两种 触发模式 第一种是打断的 第二种是mix类型的 首先 说下 BES单机模式下 提
  • Java 中的Object串行化(Serializable)

    假如你想保存一个对象 object 则这个对象所属类必须实现Serializable接口 当串行化一个对象时 Java会保存对象的完整的 对象图 即对该对象引用的其他对象 也进行串行化 当然 那些 其他对象 也要实现Serializable
  • web前端开发—Flex布局

    目录 Flex布局 1 思考 2 Flex布局 弹性布局 3 作用 4 设置方式 5 组成部分 6 主轴对齐方式 7 侧轴对齐方式 8 伸缩比 9 主轴方向 10 弹性盒子换行 Flex布局 目标 能够使用Flex布局模型灵活 快速的开发网
  • 初探webAssembly

    1 WebAssembly是什么 一种运行在现代网络浏览器中的新型代码 并且提供新的性能特性和效果 W3C WebAssembly Community Group开发的一项网络标准 对于浏览器而言 WebAssembly 提供了一条途径 让