「技术分享」WebAssembly能否重新定义前端开发模式?

如果提及近年来让人最为兴奋的新技术,非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 的灵活性。

二者性能对比

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

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

  • parse : 将源码转换成抽象语法树,传递给解释器。
  • compile + optimize : 解释器生成字节码,并通过编译器(JIT)编译优化部分字节码,生成机器码。
  • re-optimize : 当发现优化代码无法被编译器优化时,重现转给解释器。
  • execute : 执行代码的过程。
  • GC: 清理内存的时间。

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

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

编译模型(LLVM)

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

  1. 模块化设计(三段式:前端、优化器、后端),代码更为清晰和便于排查问题,前端负责语法解析,生成字节码;优化器负责优字节码;后端负责生成相应平台的机器码;
  2. 语言无关的中间代码,可以无限扩展而又不伤害可调试性;
  3. 作为工具和函数库,易于实现新的基于编程语言的优化编译器或VM。

WebAssembly 与LLVM结合

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

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

注:具体的代码和Demo示例将在grapecity的公开课中进行演示,欢迎各位同学点击文末“了解更多”观看。

项目实战: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):

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

JS:

项目结构

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

结语

通过简单介绍 WebAssembly 的应用场景和主要特性,我们能更好地够理解 WebAssembly 技术的演变过程。如果您想更详细的学习相关内容,可以点击下方“了解更多”观看视频进行学习。

(0)

相关推荐

  • JS是如何计算 1+1=2 的?

    身为程序员多年,作者今天突然对这件事感到十分好奇了.我问计算机芸芸部件,1+1究竟是如何计算的,他们都茫然的看着我. 打开谷歌浏览器->Console面板,大脑向双手不停发送生物电信号,肌肉细胞 ...

  • Go1.17.2 发布暨 WebAssembly 入门教程

    昨天凌晨,Go 官方发布了 Go1.17.2 和 1.16.9,这是两个小版本,重要修复一个安全问题. 从使用 GOARCH=wasm GOOS=js 构建的 WASM 模块调用函数时,传递非常大的参 ...

  • 老司机带你秒懂内存管理 - 第一部(共三部)

    原文地址:A crash course in memory management 原文作者:Lin Clark 译者:黑黑 校对者:Bob 要理解为什么将 ArrayBuffer 和 SharedAr ...

  • JavaScript内部原理:浏览器的内幕

    简介 Javascript 是一种奇怪语言,有些人喜欢它,有些人讨厌它.它有许多独特的机制,这些机制在其他流行语言中不存在,也没有对应的机制,还有突出明显的就是代码的执行顺序 了解浏览器环境,它的组成 ...

  • 标梵看到针对未来5年的网络发展预测推断

    RichardFeldman是<ElminAction>的作者,他在2019年的ReactiveConf上预测了Web开发未来5年的发展,很有趣,分享给大家. 假如你有机会从头开始一项工程 ...

  • 「技术分享」胖哥肉蟹煲的制作(附香料油秘制酱配方)

    「技术分享」胖哥肉蟹煲的制作(附香料油秘制酱配方) 2018-12-14 19:39·品天下美食大课堂

  • 「知识分享」臭氧氧化技术的发展史及技术原理

    臭氧,化学式为O3,又称三原子氧.超氧,因其类似鱼腥味的臭味而得名,在常温下可以自行还原为氧气.比重比氧大,易溶于水,易分解.由于臭氧是由氧分子携带一个氧原子构成,决定了它只是一种暂存状态,携带的氧原 ...

  • 「养殖分享」养鸡人,学会这些,咱也算半个禽病技术老师(三)

    本篇我们继续来学习,主要叙述如何从剖剪症状来判断疾病. 根据解剖症状断鸡病 1.心脏 一层纤维素性渗出物提示大肠杆菌感染. 心冠脂肪出血提示新城疫或流感. 幼雏鸡心脏变形提示沙门氏菌感染. 青年鸡.成 ...

  • 「园林绿化种植技术分享」11个问题及解决方法

    「园林绿化种植技术分享」11个问题及解决方法

  • 「病案分享」3日高热,依阳明四法而解

    原创 许家栋 谦川中医 病案分享 阔别数月,免费医案分享又悄悄地上线了.近期经典经方的相关课程已陆续与各位同道见面,想必各位同道在学习相关课程中受益匪浅,但又苦于无从施展练习,那么我们回来啦!接下来将 ...

  • 「病例分享」中医辨证施治7副Y解决带状疱疹

    最近接诊的一位带状疱疹的男性患者,因为疱疹疼痛瘙痒的问题,找到我这边给看诊.诊疗过程了解到这位患者是位银行从业者,得知患带状疱疹刚8天的时间,便积极就医治疗. 经辨证后发现,患者属于脾肺湿热.肝胆火旺 ...

  • 空巢老人的心理活动「真实分享」

        我们每一个人都有过空巢时期,也有过空巢生活,所以空巢生活并不可怕,更不需要别人来怜悯.空巢本身就是生活的一部分,真正懂得生活的人,从来不会抱怨自己的空巢境遇,而是依着命运的安排努力创造属于自己 ...

  • 「干货分享」高清臂丛神经分支、走形及分布图解

    断层说中医康复2021-01-30 09:55:49 手麻.颈紧.肩膀疼.后背麻胀,你可曾想过这些症状是由于臂丛神经出现问题引起的! 今天给大家带来的臂丛的线条图解,值得收藏学习! 臂丛的分支 1 由 ...

  • 「技术人生」第2篇:学会分析事物的本质

    作者:贺科学 技术一号位不是岗位,更多的是技术人员在公司中做事的一种心态,这个系列的文章适合所有想要对日常工作"知其然更知其所以然"的技术人,借助理论工具的指引,结合自己的实践经历 ...