WebAssembly之二维绘图测试
前言
最近看boss直聘上,WebAssembly 的需求挺多的,主要涉及音视频处理、图形图像、2D、3D、游戏开发等项目。
而最近我正好遇到一个二维图形优化的需求,所以就想看看WebAssembly 能否提高项目的运行速度。
1-WebAssembly 简介

WebAssembly简称wasm,是一个低级编程语言。
WebAssembly是便携式的抽象语法树,被设计来提供比JavaScript更快速的编译及执行。
WebAssembly可以让C/C++程序在浏览器内运行。
WebAssembly具有以下限制:
通常,WebAssembly 不允许与DOM直接交互。所有交互都必须通过 JavaScript 互操作进行。
没有垃圾收集(garbage collection)机制。
安全问题,比如容易隐藏恶意代码。
2-WebAssembly+canvas 2d 绘图测试
接下来我会通过Google的 canvaskit 工具来辅助测试WebAssembly+canvas 2d 的运行速度。
CanvasKit是以WASM为编译目标的Web平台图形绘制接口,其目标是将Skia的图形API导出到Web平台。所以我们可以直接用WebAssembly 开发web端的图形项目。
1.在自己的项目中安装canvaskit-wasm
2.建立一个测试文件。
01-wasm绘图测试.html
在上面的代码中,我画了50000个透明的矩形,并且通过请求动画帧来驱动动画,效果如下:

console.log(newTime - time) 打印结果如下:

初次绘图用时206,之后的刷新频率在170-190之间,平均值可以取180。
接下来我们对比原生的canvas2d 看看。
2-原生canvas2d 绘图测试
接下来我依旧会画50000个透明的矩形。
02-canvas2d绘图测试.html
效果和之前一样:

console.log(newTime - time) 打印结果如下:

初次绘图用时92,之后的刷新频率在80-90之间,平均值可以取85。
当前原生canvas2d 竟然比wasm快了一倍,我们暂且不做分析,再看一下WebGL的绘图速度。
3-原生WebGL 绘图测试
接下来我依旧会画50000个透明的矩形。
03-WebGL绘图测试.html
效果如下:

console.log(newTime - time) 打印结果如下:

初次绘图用时4903,之后的刷新频率在7185-12630之间,平均值可以取10000。
4-结果分析
下图是我们之前的测试结果:

由此可知:
canvas2d 在绘制简单图形的时候,速度最快。
wasm 要比canvas2d 慢一倍。
WebGL 最慢,且极慢。
对于这个结果,我考虑到以下可能原因:
canvas2d之所以最快,是它在绘制简单的二维图形,或者开发简单的二维项目的时候,具备主场优势,因为canvas2d 本身就是为二维而生的。
wasm 的编译和执行速度快,我是深信不疑的,毕竟是Google出品。但它之所以比原生canvas2d 慢,我想它应该还没有发挥出自己的优势,至于如何在二维项目中发挥其最大优势,还有待研究。
WebGL 最慢的原因是它擅长GPU并行渲染,而在渲染简单图形的时候,因为它要走一些复杂逻辑,比如着色器与js间的数据传输,反而渲染速度要比原生canvas 慢很多很多。
总结
最后,我个人认为,若只是开发简单的二维项目,不涉及复杂的光栅化,或者大量的逐像素操作,直接使用原生canvas2d 开发即可,因为适合的才是最好的。
下一章,我会在逐像素操作方面,对比一下canvas2d、wasm和WebGL的渲染速度。