IT技术之家

首页 > Android

Android

Day 221/300 JavaScript中的拓展——WebAssembly基本介绍_Arden Zhao

发布时间:2022-10-24 18:00:15 Android 0次 标签:javascript rust 前端
(一)需求在很多新技术中看到了WebAssembly的描述,但不知道到底WebAssembly是什么。于是搜集记录下~(二)WebAssembly1、为什么会有WebAssembly的诞生?对于网络平台而言,这具有巨大的意义——这为客户端app提供了一种在网络平台以接近本地速度的方式运行多种语言编写的代码的方式;在这之前,客户端app是不可能做到的。而且,你在不知道如何编写WebAssembly代码的情况下就可以使用它。WebAssembly的模块可以被导入的到一个网络app(或Node.js)中...

(一)需求

在很多新技术中看到了WebAssembly的描述,但不知道到底WebAssembly是什么。于是搜集记录下~

(二)WebAssembly

1、为什么会有WebAssembly的诞生?

对于网络平台而言,这具有巨大的意义——这为客户端app提供了一种在网络平台以接近本地速度的方式运行多种语言编写的代码的方式;在这之前,客户端app是不可能做到的。

而且,你在不知道如何编写WebAssembly代码的情况下就可以使用它。WebAssembly的模块可以被导入的到一个网络app(或Node.js)中,并且暴露出供JavaScript使用的WebAssembly函数。JavaScript框架不但可以使用WebAssembly获得巨大性能优势和新特性,而且还能使得各种功能保持对网络开发者的易用性。

有一个场景是,JS在移动设备上,会比原生应用(Android,IOS)慢很多,于是W3C社区就想创造了WebAssembly的技术作为JS的补充。

2、WebAssembly的定义

(1)定义

WebAssembly/wasm WebAssembly 或者 wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式。是JavaScript的拓展和补充;

WebAssembly 是由主流浏览器厂商组成的 W3C 社区团体 制定的一个新的规范。

WebAssembly是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。它设计的目的不是为了手写代码而是为诸如C、C++和Rust等低级源语言提供一个高效的编译目标。

    为 WebAssembly 设计的二进制格式可以被原生解码,这比 JavaScript 的解析要快很多(实验表明至少要快20倍以上)。在移动设备上,较大的编译后代码仅仅解析就需要占用 20-40 秒,所以原生解码(特别是为了比 gzip 更好的压缩效果时需要与其他技术例如 streaming结合的时候)对于提供良好的零负载用户体验是非常重要的。为了避免同步 asm.js 针对AOT-编译的约束,并保证在没有针对 asm.js 的特殊优化的设备上也有好的性能表现,用一个新的标准使得我们能够更容易的添加这些(http://webassembly.org.cn/docs/future-features/),这需要具有原生层面的性能表现能力。

(2)特点

【高效】快速、高效、可移植——通过利用常见的硬件能力,WebAssembly代码在不同平台上能够以接近本地速度运行。【开放】可读、可调试——WebAssembly是一门低阶语言,但是它有确实有一种人类可读的文本格式(其标准即将得到最终版本),这允许通过手工来写代码,看代码以及调试代码。【安全】保持安全——WebAssembly被限制运行在一个安全的沙箱执行环境中。像其他网络代码一样,它遵循浏览器的同源策略和授权策略。【标准】不破坏网络——WebAssembly的设计原则是与其他网络技术和谐共处并保持向后兼容。WebAssembly 可以被 JavaScript 调用,进入 JavaScript 上下文,也可以像 Web API 一样调用浏览器的功能。当然,WebAssembly 不仅可以运行在浏览器上,也可以运行在非web环境下。

(3)关键概念

为了理解WebAssembly如何在浏览器中运行,需要了解几个关键概念。所有这些概念都是一一映射到了WebAssembly的JavaScript API中。

模块:表示一个已经被浏览器编译为可执行机器码的WebAssembly二进制代码。一个模块是无状态的,并且像一个二进制大对象(Blob)一样能够被缓存到IndexedDB中或者在windows和workers之间进行共享(通过postMessage() (en-US)函数)。一个模块能够像一个ES2015的模块一样声明导入和导出。内存:ArrayBuffer,大小可变。本质上是连续的字节数组,WebAssembly的低级内存存取指令可以对它进行读写操作。表格:带类型数组,大小可变。表格中的项存储了不能作为原始字节存储在内存里的对象的引用(为了安全和可移植性的原因)。实例:一个模块及其在运行时使用的所有状态,包括内存、表格和一系列导入值。一个实例就像一个已经被加载到一个拥有一组特定导入的特定的全局变量的ES2015模块。

3、WebAssembly如何使用

(1)API 参考

WebAssembly

本对象是所有与WebAssembly相关功能的命名空间。

WebAssembly.Module

一个WebAssembly.Module对象包括了无状态的WebAssembly代码。该代码已经被浏览器编译并且能够通过Workers高效地共享,缓存到IndexedDB中以及多次实例化。

WebAssembly.Instance

一个WebAssembly.Instance对象是一个有状态的、可执行的模块的实例。实例对象包含所有的能够从JavaScript调用到WebAssembly代码的导出的WebAssembly函数

WebAssembly.instantiate()

WebAssembly.instantiate() 函数是编译和实例化WebAssembly代码的主要的API,它返回一个Module及其第一个实例。

WebAssembly.Memory()

一个WebAssembly.Memory 对象是一个可变长的ArrayBuffer。它拥有能够被实例存取的原始字节内存。

WebAssembly.Table()

WebAssembly.Table对象是一个可变长类型数组。它存储诸如函数引用之类的不透明值并且能够被实例存取。

WebAssembly.CompileError()

创建一个新的WebAssembly CompileError对象。

WebAssembly.LinkError() (en-US)

创建一个新的WebAssembly LinkError对象。

WebAssembly.RuntimeError()

创建一个新的WebAssembly RuntimeError对象。

(2)API DEMO

下面的示例(请参见GitHub上的Instantiate-streaming.html])演示,直接从流式底层源传输.wasm模块,然后对其进行编译和实例化,并通过ResultObject实现promise。 由于instantiateStreaming()函数接受对Response对象的promise,因此您可以直接向其传递WindowOrWorkerGlobalScope.fetch()调用,然后它将把返回的response传递给随后的函数。

var importObject = { imports: { imported_func: arg => console.log(arg) } };

WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject)
.then(obj => obj.instance.exports.exported_func())

参考链接

1、MDN

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly

2、webassembly中文网

http://webassembly.org.cn/

写在最后的话

学习路上,常常会懈怠

《有想学技术需要监督的同学嘛~》
https://mp.weixin.qq.com/s/FyuddlwRY7DsHUejCjiVug

欢迎关注我的公众号:国星聊成长
每周分享我学习到的成长/认知方法