3分钟在小程序中使用Webassembly
发布时间:2025-05-21 07:55:40 发布人:远客网络
一、3分钟在小程序中使用Webassembly
前言
2022年,使用WASM进行前端的性能优化是一件常见的事情。本文记录如何在3分钟之内在微信小程序中成功的接入WASM来优化性能。
2022年,使用WASM进行前端的性能优化是一件常见的事情。本文记录如何在3分钟之内在微信小程序中成功的接入WASM来优化性能。
毫无疑问在WASM的第一语言选择是Rust,wasm-pack的强大功能使得开发者可以专注于逻辑代码的编写,最终产物的编译以及跟js胶水层代码的粘合它都会自动帮我们生成(当然,前提是不考虑小程序场景,小程序场景的。Webassembly对象是极致阉割版本的
以color-thief这个出名的图片取主色算法为例子。首先我们去crates.io上搜索关键字,果不其然,找到了该算法的Rust版本。
使用wasm-packnew来创建一个简单的开发模版。
对于绝大多数已存在Rust算法的工程中,我们要做的事情无非就是输入输出的转换。需要将Rust数据类型与JS数据类型进行映射转换。
这里我们使用js_sys这个库来包装Rust类型为JSValue。观察JsValue::from对于基本类型i32,f32,String等等,我们可以直接转换为JsValue
可以看到通过上面的代码,忽略参数预处理的部分,我们只需要20行左右的代码便可以完成这个rusttowasm的转换。如果输入输出都是String的场景则更加简单。
在不同场景例如Web/Node.js环境使用wasm文件的api胶水层代码是不一样的。不错的是wasm-pack内置了常见环境的部署命令。我们可以通过wasm-packbuild--targetweb|Node.js|bunlder来部署在不同平台使用的npmpackage。
迁移完之后自然要跑一跑benchmark来看看性能到底有没有提升。毕竟wasm/napi这些方案不是银弹,在某些场景反而会降低应用性能。
测试了一下WASM版本的性能比起JS版本提升了6倍。Nice?
接下来进入今天的重点话题。如何在小程序中接入wasm.参考小程序官方文档理论上小程序是支持wasm的。这里我们选择的是wasm-packbuild--targetweb的产物来接入使用。
首先我们按照常规写法来引入相关代码
在小程序中对应的api名称为WXWebAssembly
这里我在生成产物的头部简单的插入了一个前置处理代码,而不是整量替换
Cannotuse'import.meta'outsideamodule
这里的目的是,在浏览器当中,我们可以通过fetchapi结合WebAssembly.instantiateStreaming来流式的下载初始化wasm文件。可惜在小程序我们并不能这么做。
所以这里我们将这段代码干掉,直接将wasm放在本地文件中加载
TextEncoderisnotdefined,不出所料,TextEncoder这个api在小程序被阉割掉了。
这里我们只能手动引入polyfill文件来提供TextEncoder
Righthandsideofinstanceofisnotaobject
果不其然在真机WebAssembly.Instanceisundefined,这个api在小程序还没有实现。于是我们打印instance的类型,删除判断代码直接固定返回值为instance
总结完上面的四个问题后,我们总不可能每次都要手动构建不同平台的产物再部署,或者每次构建小程序产物的时候都要手动改这么多地方吧。
于是出于解放生产力的考虑。这里我直接创建了一个wasmproject模版结合GithubActions来一键部署四个平台的构建产物并发布
在模版中我们集成了四个平台的构建脚本
便可以自动结合GithubAcions构建部署在web,Node.js,Bundler,Miniprogram发布的package。
假设当前的package.name为color-thief-wasm,最终会部署以下四个package
二、crypto-js-wasm: 当crypto-js遇上WebAssembly
WebAssembly(Wasm)技术简介及应用实践:crypto-js-wasm
WebAssembly(简称 Wasm)是一个实验性的低级编程语言,适用于浏览器内的客户端。它将提供比JavaScript更快的编译和执行速度。Wasm的设计目标是让开发者使用除JavaScript之外的语言,开发可以在浏览器或 Node.js中运行的二进制应用。
2.支持多种编程语言编译,如 C/C++、Rust、AssemblyScript、C#、Go等。
3.大部分Wasm标准API已被主流浏览器(如 Chrome、Firefox、Safari)和Node.js支持。
1.频繁的内存拷贝操作可能导致运行速度变慢。
2.使用 Wasm时,需要特别注意应用的内存管理。
结合Wasm技术,加密算法非常适合应用。加密算法计算量大,对性能要求高,且调用次数较少。同时,加密算法对运行时安全有一定要求。
加密算法开源软件 crypto-js已在npm上发布,支持主流哈希算法(如SHA-256、SHA-3、MD5等)、加密算法(如AES、RC4等)以及编码和填充算法。基于此,结合Wasm技术,我们开发了 crypto-js-wasm。
3.添加了Jest测试、大宝等功能。
通过npm命令即可安装crypto-js-wasm:
安装步骤简单,便于开发者快速集成。
在使用时,crypto-js-wasm的使用方式与crypto-js有所不同。需要异步加载特定算法的Wasm二进制文件,或加载所有算法的Wasm二进制文件。
为了验证性能,我们开发了专门的基准测试工具,包括本地测试和在线测试选项。基准测试结果表明,crypto-js-wasm在大部分场景下性能表现更优,某些复杂算法的性能提升甚至可达16倍以上。
得益于Wasm技术,crypto-js-wasm运行时内存不可见,增强了加密算法的安全性。但内存交换仍需通过JavaScript编写的胶水代码实现,因此加密过程内存不可见。
总结:crypto-js-wasm为使用或需要JavaScript加密算法的开发者提供了性能提升和安全性增强的解决方案。欢迎尝试并提供反馈。我们计划在crypto-js-wasm中提供更复杂的加密算法如RSA,期待您的参与和支持。
三、threejs 怎么结合 WebAssembly 优化浏览器限制
1、结合WebAssembly可以优化浏览器限制,通过将threejs的核心功能以二进制格式加载到浏览器中,可以减少解析和编译的时间,提高加载速度。这样可以更快地渲染复杂的三维场景,并且减少了对浏览器的资源消耗。使用WebAssembly可以将一些计算密集型的任务交给WebAssembly处理,减轻JavaScript的负担,提高整体的性能。
2、例如,可以将一些复杂的数学计算或图形处理操作交给WebAssembly来执行,从而提高threejs的渲染效率。WebAssembly还具有多线程特性,可以将一些耗时的任务分配给不同的线程并行处理,进一步提高了性能。通过合理地利用多线程,可以更好地利用现代浏览器的多核处理能力,加快渲染速度。
3、结合WebAssembly可以优化浏览器限制,提高threejs的性能和效率。通过将核心功能以二进制格式加载、与JavaScript交互和利用多线程等方式,可以更高效地运行threejs,并且提供更好的用户体验。
4、WebAssembly是一种可以在浏览器中运行高性能的二进制格式,它将代码编译成机器码,使得运行速度更快,并且可以更好地利用硬件资源。这种技术的引入,使得threejs在浏览器中的运行变得更加高效。
5、结合WebAssembly,threejs可以更好地应对浏览器对资源的限制。在传统的JavaScript环境下,threejs需要消耗大量的内存和CPU资源来运行复杂的三维场景,这在一定程度上限制了threejs的应用范围。而通过结合WebAssembly,threejs可以将核心功能以二进制格式加载,减少解析和编译的时间,从而提高加载速度。
6、此外,WebAssembly还可以与JavaScript进行交互,将一些计算密集型的任务交给WebAssembly处理,减轻JavaScript的负担。这对于一些复杂的数学计算或图形处理操作来说尤为重要,因为这些操作通常需要大量的计算资源,而将它们交给WebAssembly处理,可以显著提高threejs的渲染效率。
7、更重要的是,WebAssembly还具有多线程特性,可以将一些耗时的任务分配给不同的线程并行处理。这进一步提高了性能,使得threejs可以更好地利用现代浏览器的多核处理能力,加快渲染速度。这种技术的结合,使得threejs在浏览器中的运行变得更加高效,为用户提供更好的体验。
8、综上所述,结合WebAssembly可以优化浏览器限制,提高threejs的性能和效率。通过将核心功能以二进制格式加载、与JavaScript交互和利用多线程等方式,可以更高效地运行threejs,并且提供更好的用户体验。