跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • WebAssembly 能否重新定义前端开发模式?
未分類
2 11 月 2020

WebAssembly 能否重新定义前端开发模式?

WebAssembly 能否重新定义前端开发模式?

資深大佬 : GrapeCityChina 3

如果提及近年来让人最为兴奋的新技术,非 WebAssembly 莫属。作为一种低级的类汇编语言,WebAssembly以紧凑二进制的格式存储,为 C/C++, Rust 等拥有低级内存的模型语言提供了新的编译目标。正因如此,WebAssembly 体积更小,可以以接近原生性能的速度运行。

WebAssembly 技术本身具有非常多的优点,虽始于浏览器但已经开始不断地被各个语言及平台所集成,在实际的工业化落地中,区块链、边缘计算、游戏及图像视频等多个领域都依靠 WebAssembly 创造出了让人称赞的产品。

WebAssembly 的应用场景

· 编译器(编译链)

· 多媒体剪辑

· 游戏

· 图像识别

· VR+虚拟现实

· 直播视屏特效

· 游戏、应用分发服务

· 服务器端运行不受信任的代码

· 移动端混合应用

· P2P 应用

· …

WebAssembly 的主要特性

· 快速、高效、可移植

· 可读、可调试

· 安全,遵循浏览器同源策略和授权策略,运行在沙箱环境中

· 与其他 web 技术兼容(JS)

WebAssembly VS Javascript

既然提到了 Web 技术,就不得不提另一款在 Web 项目开发中大放异彩的脚本语言 Javascript 。1995 年,Brendan Eich 用了不到 10 天就创建了 Javascript,其最初主要应用于表单验证,而非以速度见长。随着各类应用功能的复杂化,受限于 JavaScript 语言本身动态类型和解释执行的设计,其性能问题逐渐凸现。

2008 年,围绕着浏览器性能开展的大战终于在各大浏览器厂商间爆发,在先后经历了即时编译器( JITs ),以及用 Node.js 和 Electron 构建应用程序的时期后,WebAssembly 有望成为 JS 引擎突破下一性能瓶颈的转折点。

为此,这两者经常被用于比较,甚至一度出现 WebAssembly 终将替代 Javascript 的言论。的确,作为类汇编语言,WebAssembly 解决了 Javascript 最常为人诟病的性能问题,也正是基于此,WebAssembly 注定不适合开发人员手写代码,只能为其他语言提供一个编译目标。

因此,这两种技术的关系不是竞争,反而更像是合作共赢。通过 Javascript API,你可以将 WebAssembly 模块加载到你的页面中。也就是说,你可以通过 WebAssembly 来充分利用编译代码的性能,同时保持 Javascript 的灵活性。

WebAssembly 能否重新定义前端开发模式?

二者性能对比

下图为我们展现了 JS 引擎运行程序和运行 Wasm 的耗时对比:

WebAssembly 能否重新定义前端开发模式?

JS 引擎运行程序时,需要经历源码转换( parse )、生成字节码( compile + optimize )、编译器优化( re-optimize )、代码执行( execute )和内存清理( GC )这五个阶段:

· parse : 将源码转换成抽象语法树,传递给解释器。

· compile + optimize : 解释器生成字节码,并通过编译器( JIT )编译优化部分字节码,生成机器码。

· re-optimize : 当发现优化代码无法被编译器优化时,重现转给解释器。

· execute : 执行代码的过程。

· GC: 清理内存的时间。

大部分情况下,JS 在执行阶段将字节码编译成机器码,这一阶段十分耗时。(这是由于 JS 的动态性所导致,相同的代码会被不同的类型重新编译)。而 Wasm 不需要被解析,也不需要在运行时动态检测数据类型,由于它已经是字节码了,所以只需要简单解码,即可包含所有的类型信息。

正是因为 Wasm 的大部分优化工作已经在 LLVM 的前端部分完成了,所以编译优化的工作很少,这便是其高性能的主要体现。

编译模型(LLVM)

WebAssembly 能否重新定义前端开发模式?

LLVM ( Low-Level-Virtural-Machine ), 底层虚拟机架构,优点包括:

  1. 模块化设计(三段式:前端、优化器、后端),代码更为清晰和便于排查问题,前端负责语法解析,生成字节码;优化器负责优字节码;后端负责生成相应平台的机器码

  2. 语言无关的中间代码,可以无限扩展而又不伤害可调试性

  3. 作为工具和函数库,易于实现新的基于编程语言的优化编译器或 VM

WebAssembly 与 LLVM 结合

WebAssembly 能否重新定义前端开发模式?

WebAssembly 与 LLVM 结合,不需要为各个语言额外添加前端编译工具,中间的 IL 可以不断地优化,仅需添加一个“后端”,就可以让大部分语言编译成 wasm 。这个“后端”不同于之前提到的后端,它不会直接生成机器码,它生成的 wasm,会由浏览器 wasm 运行时负责编译运行。

这就是 WebAssembly 的编译原理, 既然 WebAssembly 的核心目标是与 Javascript 等 Web 技术兼容, 那么其兼容到底程度如何?下面,我们将通过项目实战来验证。

项目实战:WebAssembly + Javascript

在进入项目实战之前,大家需要理解一个核心概念,即 JavaScript 为何能完全控制 WebAssembly 代码,并执行下载和编译运行:

核心概念

· Module (模块):该模块表示一个已经被浏览器编译为可执行机器码的 wasm 二进制序列。模块是无状态的,它可以被缓存在 IndexedDB 中或者在 workers 之间共享,也能够像 JS 一样导入导出。

· Memory (内存):连续大小可变的字节数组,能够被 Wasm 和 JS 同步读写。它可以用来在 JS 和 Wasm 之间传递数据,进行通信。

· Table (表格):带类型的大小可变的数组,表格里存储了不能作为原始字节存储在内存里的对象的引用。

· Instance (实例):一个模块及其在运行时的所有状态,包括内存,表格,以及导入的值。

可见,JavaScript API 为开发者提供了创建模块、内存、表格和实例的能力。

通过一个 WebAssembly 实例,JavaScript 能够调用该实例暴露的函数,把 JavaScript 函数导入到 WebAssembly 实例中,WebAssembly 也能调用 JavaScript 函数。

另外,WebAssembly 不能直接读写 DOM,只能调用 JavaScript,并且只能传入整形和浮点型的原始数据作为参数。因此,JavaScript 能够完全控制 WebAssembly 代码实现下载、编译、运行,JavaScript 开发者也可以把 WebAssembly 想象成一个生成高性能函数的 JavaScript 特性。

代码示例

wasm(Rust):

WebAssembly 能否重新定义前端开发模式?

wasm_bindgen 主要用来生成一些胶水代码,简化开发者在 JS 和 wasm 之间的方法调用。

JS:

WebAssembly 能否重新定义前端开发模式?

项目结构

WebAssembly 能否重新定义前端开发模式?

IDE

VSCode+插件 Rust

执行步骤

  1. Install Rust:https://www.rust-lang.org/tools/install 打开 cmd,输入 cargo 确认安装是否正确。

  2. 安装 wasm 编译工具:$ cargo install wasm-pack

  3. 创建 rust-wasm 工程: $ cargo new –-lib wasmlib

  4. Build: $ wasm-pack build

大佬有話說 (1)

  • 主 資深大佬 : GrapeCityChina

    具体的代码和 Demo 示例将在 11 月 11 日下午 2 点的公开课中进行演示,欢迎各位同学报名收看,报名地址: http://live.vhall.com/756593738 。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具