什么是 webassembly

在 2019 年 12 月之前,如果你要编写一个web页面,那一定离不开 html、css、js 这三个好兄弟。在 2019 年 12 月之后 W3C 宣布 webassembly 加入了他们。为什么要在三兄弟后加入 webassembly ?它和之前的有什么区别么?以 js 为对比,我们具体看一下它们的区别。

wasm 与 js 的区别

js 是一种解释型语言,它代码运行之前不会进行编译工作,而是在执行的过程中实时编译。为了让边编译边执行能够顺利进行,我们拥有了 js 引擎。

wasm 则与之不同,它本身不是一种编程语言,而是一种字节码的标准,可以通过不同种类的高级编程语言,比如 Rust、Go、Python 等等,通过各自编译器将代码转换成 .wasm 文件,放入到浏览器预先做好的 wasm 虚拟机当中运行。

同时这种与 js 不同,可以预先运行的特色,也给 wasm 带来了一些优势:

  • 拥有一套完成的语义: wasm 这套体积小且加载快的二进制格式的完整语义,可以让硬件充分发挥能力以达到原生的执行效率。

  • 编译和优化时间所需时间较少: 相比 js 作为一个动态类型需要多次编译代码,wasm 让文件在推送到服务器前就进行了众多优化,能够有效减少编译和优化时间。

  • 执行速度更快: wasm 是二进制文件,它的指令更接近机器码,执行起来的速度相比 js 更快。

  • 垃圾回收效率更高: wasm 目前并不支持自动垃圾回收,垃圾回收都是手动控制的,比自动垃圾回收效率更高。

当然如果只是这么说,我们并不能很直观的感受出这些优势究竟有多大,刚好目前浏览器已经支持了以 wasm 规范的虚拟机。

接下来,我们通过一个 Chrome 与 Safari 的实例测试,来感受一下。

wasm与js执行速度比较

首先我们用原生的 js 写一段 fib 代码测试时间,代码内容如下:


<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head> <body>
<script>
function fibonacci(n) {
if (n == 0 || n == 1)
return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
function fibonacciTime() {
console.time("js")
fibonacci(40)
console.timeEnd("js")
}
fibonacciTime()
</script>
</body> </html>

用 live-server 测试时间,用时 1275 毫秒到 1329 毫秒。

然后我们用 Rust 转义成 wasm 再次测试。特别需要注意的是,测试用到的算法都是最普通的递归迭代,在实际使用中我们还可以使用动态规划来再次优化。

言归正传,然后我们用 rust-wasm 编译器将用 rust 写好的 fib 代码转换成 wasm 文件。

下载 wasm 编译器:

curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

配置 Cargo.toml:


[package]
name = "wasm"
version = "0.2.0"
authors = ["hzjsea"]
edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib]
crate-type = ["cdylib"]
path = "src/main.rs" [dependencies]
wasm-bindgen = "0.2.48"
chrono = "0.4.19"

main.rs:


use chrono::Utc;
use wasm_bindgen::prelude::*;
use std::time::Instant; #[wasm_bindgen]
pub fn fib(n: i32) -> i32 {
match n {
0 => 1,
1 => 1,
_ => fib(n - 1) + fib(n - 2),
}
} pub fn main(){
let result = fib(40);
println!("{:?}", result);
}

挂载wasm文件,即类似 vue,使用 index.html 把 wasm.js 文件挂载起来:


<script type="module">
main() async function main() {
const wasm = await import('/pkg/wasm.js')
await wasm.default('/pkg/wasm_bg.wasm')
console.time("rust")
console.log(wasm.fib(40))
console.timeEnd("rust")
} function fibonacci(n) {
if(n==0 || n == 1)
return n;
return fibonacci(n-1) + fibonacci(n-2);
}
function fibonacciTime(){
console.time("js")
fibonacci(40)
console.timeEnd("js")
}
fibonacciTime()
</script>

之后用编译器编译 Rust 代码生成 .wasm 文件:


wasm-pack build --target web --no-typescript --mode normal

然后我们可以明显看到,在相同的 live-server 测试下时间相差一倍左右。

因为此次编译指定不生成 wasm 的 ts 版本。所有只有上面的几个文件,其中:

  • package.json

{
"name": "wasm",
"collaborators": [
"hzjsea"
],
"version": "0.2.0",
"files": [
"wasm_bg.wasm",
"wasm.js"
],
"module": "wasm.js",
"sideEffects": false
}

指定打包的各类属性

  • wasm_bg.wasm

wasm.js转义后的二进制文件

  • wasm.js

由rust代码转移过来的wasm.js文件。

wasm 的组件库

看完了实例测试,我们不能略过测试中提到的 Rust。Rust 中有个类似于 react 的框架,叫做Yew。关于 Yew 官方[https://github.com/yewstack/yew]描述如下:

Yew is a modern Rust framework for creating multi-threaded front-end web apps with WebAssembly.

  • Features a macro for declaring interactive HTML with Rust expressions. Developers who have experience using JSX in React should feel quite at home when using Yew.

  • Achieves high performance by minimizing DOM API calls for each page render and by making it easy to offload processing to background web workers.

  • Supports JavaScript interoperability, allowing developers to leverage NPM packages and integrate with existing JavaScript applications.

计时器

大致看完了 Rust,如果你还想看更多的 WebAssembly 流程,官方提供的一个计时器的练手项目可以满足你的需求

项目地址 https://yew.rs/docs/zh-CN/getting-started/build-a-sample-app

主要可以看下 lib.rs 这个文件

总结与思考

虽然 webassembly 作为一种新的 web 技术常常被提起,但是因为其工具链的调试困难,包体积过大等等问题还在解决的过程中,同时也表明了 wasm 并不可能在短时间内直接代替 js,他们之间更多的是一种互补合作的关系。但不可否认的是,适合 webassembly 场景的项目会在未来的一段时间内不断的出现,大家可以多多了解一下。

https://www.jianshu.com/writer#/notebooks/164311/notes/88906048/preview的更多相关文章

  1. 接口测试之——Charles抓包及常见问题解决(转载自https://www.jianshu.com/p/831c0114179f)

    简介 Charles其实是一款代理服务器,通过成为电脑或者浏览器的代理,然后截取请求和请求结果达到分析抓包的目的.该软件是用Java写的,能够在Windows,Mac,Linux上使用,安装Charl ...

  2. [转]https://www.jianshu.com/p/06443248f4d8

    eos是什么? 原文 https://www.jianshu.com/p/06443248f4d8 简介 用一句话来定义eos,即:区块链操作系统,支持在它之上构建dapp,支持智能合约.帐户.身份验 ...

  3. Zabbix调优不完全指南(https://www.jianshu.com/p/2d911d55448f)

    从学习搭建zabbix到完成各类监控.调优.二次开发已经过去了两年,期间通过QQ学习群.zabbix官方社区.各个技术博客整理学习了不少关于各种报错的处理方法,现在将常见的一些报错处理方法整理出来分享 ...

  4. jar与war包区别,转自https://www.jianshu.com/p/3b5c45e8e5bd

    https://www.jianshu.com/p/3b5c45e8e5bd

  5. fastdfs(https://www.jianshu.com/p/1c71ae024e5e)

    参考 官方网站:https://github.com/happyfish100/ 配置文档:https://github.com/happyfish100/fastdfs/wiki/ 参考资料:htt ...

  6. https://www.jianshu.com/p/1038c6170775

    import os # 方法一: os.walk实现 def items_dir(rootname): l = [] for main_dir, dirs, file_name_list in os. ...

  7. Redis 单线程却能支撑高并发 - 简书 https://www.jianshu.com/p/2d293482f272

    小结: 1.在 I/O 多路复用模型中,最重要的函数调用就是 select,该方法的能够同时监控多个文件描述符的可读可写情况:2.Redis 服务采用 Reactor 的方式来实现文件事件处理器(每一 ...

  8. 当我写下Map<String,Object> map = new HashMap<>() https://www.jianshu.com/p/6b2e350e99be

    当我写下Map<String,Object> map = new HashMap<>();我到底在写什么? 我什么时候会写HashMap? 一个函数同时需要返回 多种 状态的情 ...

  9. Asp.Net Core 第01局:项目创建和部署 转载https://www.jianshu.com/p/9c9750e23b3e

    总目录 一.前言 本文通过从项目创建到部署,简单介绍Asp.Net Core. 二.环境 1.Visual Studio 2017 2.Asp.Net Core 2.2 三.开局 第一手:创建项目   ...

随机推荐

  1. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

  2. 【Git】3. Git重要特性-分支操作,合并冲突详解

    一.分支介绍 在版本控制过程当中,有时候需要同时推进多个任务,这样的话,就可以给每个任务创建单独的分支. 有了分支之后,对应的开发人员就可以把自己的工作从主线上分离出来,在做自己分支开发的时候,不会影 ...

  3. 在网页添加 Live2D 看板娘

    只需要将以下代码粘贴到 标签中即可 <!--看板娘--> <script src="https://cdn.jsdelivr.net/npm/jquery/dist/jqu ...

  4. json的解析和生成

    相比于xml,json的主要特点是数据小,解析速度快,但是描述性差. java中常见的json解析方法有Gson.Jackson.JSON.simple. 从解析速度上来看,Gson适合解析小数据量, ...

  5. 源码简析XXL-JOB的注册和执行过程

    一,前言 XXL-JOB是一个优秀的国产开源分布式任务调度平台,他有着自己的一套调度注册中心,提供了丰富的调度和阻塞策略等,这些都是可视化的操作,使用起来十分方便. 由于是国产的,所以上手还是比较快的 ...

  6. 从刚毕业的5K测试到20K测试大佬,与薪资相匹配的永远是实力!

    有个话题"软件测试的工资高还是开发者的工资高?"软件测试和软件开发门槛有差异,在职业起步阶段收入也会有一定的差异,这算是行业内公开的秘密.但随着工作年限的增加,经验的逐步积累,软件 ...

  7. Vue3能不能用到生产环境?

    最近,有不少朋友问我:"十三,看你写了几个Vue3的项目,你觉得Vue3能用到生产环境了吗?"结合自己的想法和尤大直播说的话,给一点建议. 别问我!没结果,除非花手摇过我. 我不是 ...

  8. 使用gulp搭建项目

    项目源码地址 前期准备工作 首先确保本机安装了 node gulp中文文档 安装 gulp 命令行工具 npm install --global gulp-cli 在项目目录下创建 package.j ...

  9. [bug]MySQL [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause

    参考 http://www.10qianwan.com/articledetail/220315.html

  10. [刷题] 437 Paths Sum III

    要求 给出一棵二叉树及一个数字sum,判断这棵二叉树上存在多少条路径,其路径上的所有节点和为sum 路径不一定始于根节点,终止于叶子节点 路径要一直向下 思路 分情况讨论:根节点在路径上(8) / 根 ...