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

葡萄城 2020-11-09 14:29:29
技术 分享 WebAssembly 重新 新定


讲师简介:翟奔, GrapeCity GCDS项目组资深开发工程师,擅长前端、.NET Desktop技术,致力于工具链开发,喜欢尝试各种前沿技术并分享。

image.png

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

image.png

二者性能对比

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

image.png

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

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

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

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

· execute : 执行代码的过程。

· GC: 清理内存的时间。

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

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

编译模型(LLVM)

image.png

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

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

WebAssembly 与LLVM结合

image.png

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

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

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

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

image.png

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

JS:

image.png

项目结构

image.png

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 技术的演变过程。在11月11日的技术分享中,我们将基于 Webpack+Rust示例继续探讨 WebAssembly,并通过项目实战演示WebAssembly与JavaScript代码相结合的实现过程。欢迎感兴趣的同学,报名参加,报名地址:http://live.vhall.com/756593738

版权声明
本文为[葡萄城]所创,转载请带上原文链接,感谢
https://segmentfault.com/a/1190000037771311

  1. [front end -- JavaScript] knowledge point (IV) -- memory leakage in the project (I)
  2. This mechanism in JS
  3. Vue 3.0 source code learning 1 --- rendering process of components
  4. Learning the realization of canvas and simple drawing
  5. gin里获取http请求过来的参数
  6. vue3的新特性
  7. Get the parameters from HTTP request in gin
  8. New features of vue3
  9. vue-cli 引入腾讯地图(最新 api,rocketmq原理面试
  10. Vue 学习笔记(3,免费Java高级工程师学习资源
  11. Vue 学习笔记(2,Java编程视频教程
  12. Vue cli introduces Tencent maps (the latest API, rocketmq)
  13. Vue learning notes (3, free Java senior engineer learning resources)
  14. Vue learning notes (2, Java programming video tutorial)
  15. 【Vue】—props属性
  16. 【Vue】—创建组件
  17. [Vue] - props attribute
  18. [Vue] - create component
  19. 浅谈vue响应式原理及发布订阅模式和观察者模式
  20. On Vue responsive principle, publish subscribe mode and observer mode
  21. 浅谈vue响应式原理及发布订阅模式和观察者模式
  22. On Vue responsive principle, publish subscribe mode and observer mode
  23. Xiaobai can understand it. It only takes 4 steps to solve the problem of Vue keep alive cache component
  24. Publish, subscribe and observer of design patterns
  25. Summary of common content added in ES6 + (II)
  26. No.8 Vue element admin learning (III) vuex learning and login method analysis
  27. Write a mini webpack project construction tool
  28. Shopping cart (front-end static page preparation)
  29. Introduction to the fluent platform
  30. Webpack5 cache
  31. The difference between drop-down box select option and datalist
  32. CSS review (III)
  33. Node.js学习笔记【七】
  34. Node.js learning notes [VII]
  35. Vue Router根据后台数据加载不同的组件(思考->实现->不止于实现)
  36. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  37. 【JQuery框架,Java编程教程视频下载
  38. [jQuery framework, Java programming tutorial video download
  39. Vue Router根据后台数据加载不同的组件(思考->实现->不止于实现)
  40. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  41. 【Vue,阿里P8大佬亲自教你
  42. 【Vue基础知识总结 5,字节跳动算法工程师面试经验
  43. [Vue, Ali P8 teaches you personally
  44. [Vue basic knowledge summary 5. Interview experience of byte beating Algorithm Engineer
  45. 【问题记录】- 谷歌浏览器 Html生成PDF
  46. [problem record] - PDF generated by Google browser HTML
  47. 【问题记录】- 谷歌浏览器 Html生成PDF
  48. [problem record] - PDF generated by Google browser HTML
  49. 【JavaScript】查漏补缺 —数组中reduce()方法
  50. [JavaScript] leak checking and defect filling - reduce() method in array
  51. 【重识 HTML (3),350道Java面试真题分享
  52. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  53. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  54. [re recognize HTML (3) and share 350 real Java interview questions
  55. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  56. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  57. 【重识 HTML ,nginx面试题阿里
  58. 【重识 HTML (4),ELK原来这么简单
  59. [re recognize HTML, nginx interview questions]
  60. [re recognize HTML (4). Elk is so simple