WebAssembly之二維繪圖測試
前言
最近看boss直聘上,WebAssembly 的需求挺多的,主要涉及音視頻處理、圖形圖像、2D、3D、游戲開發(fā)等項(xiàng)目。
而最近我正好遇到一個(gè)二維圖形優(yōu)化的需求,所以就想看看WebAssembly 能否提高項(xiàng)目的運(yùn)行速度。
1-WebAssembly 簡介

WebAssembly簡稱wasm,是一個(gè)低級(jí)編程語言。
WebAssembly是便攜式的抽象語法樹,被設(shè)計(jì)來提供比JavaScript更快速的編譯及執(zhí)行。
WebAssembly可以讓C/C++程序在瀏覽器內(nèi)運(yùn)行。
WebAssembly具有以下限制:
通常,WebAssembly 不允許與DOM直接交互。所有交互都必須通過 JavaScript 互操作進(jìn)行。
沒有垃圾收集(garbage collection)機(jī)制。
安全問題,比如容易隱藏惡意代碼。
2-WebAssembly+canvas 2d 繪圖測試
接下來我會(huì)通過Google的?canvaskit?工具來輔助測試WebAssembly+canvas 2d 的運(yùn)行速度。
CanvasKit是以WASM為編譯目標(biāo)的Web平臺(tái)圖形繪制接口,其目標(biāo)是將Skia的圖形API導(dǎo)出到Web平臺(tái)。所以我們可以直接用WebAssembly 開發(fā)web端的圖形項(xiàng)目。
1.在自己的項(xiàng)目中安裝canvaskit-wasm
2.建立一個(gè)測試文件。
01-wasm繪圖測試.html
在上面的代碼中,我畫了50000個(gè)透明的矩形,并且通過請(qǐng)求動(dòng)畫幀來驅(qū)動(dòng)動(dòng)畫,效果如下:

console.log(newTime - time) 打印結(jié)果如下:

初次繪圖用時(shí)206,之后的刷新頻率在170-190之間,平均值可以取180。
接下來我們對(duì)比原生的canvas2d 看看。
2-原生canvas2d 繪圖測試
接下來我依舊會(huì)畫50000個(gè)透明的矩形。
02-canvas2d繪圖測試.html
效果和之前一樣:

console.log(newTime - time) 打印結(jié)果如下:

初次繪圖用時(shí)92,之后的刷新頻率在80-90之間,平均值可以取85。
當(dāng)前原生canvas2d 竟然比wasm快了一倍,我們暫且不做分析,再看一下WebGL的繪圖速度。
3-原生WebGL 繪圖測試
接下來我依舊會(huì)畫50000個(gè)透明的矩形。
03-WebGL繪圖測試.html
效果如下:

console.log(newTime - time) 打印結(jié)果如下:

初次繪圖用時(shí)4903,之后的刷新頻率在7185-12630之間,平均值可以取10000。
4-結(jié)果分析
下圖是我們之前的測試結(jié)果:

由此可知:
canvas2d 在繪制簡單圖形的時(shí)候,速度最快。
wasm 要比canvas2d 慢一倍。
WebGL 最慢,且極慢。
對(duì)于這個(gè)結(jié)果,我考慮到以下可能原因:
canvas2d之所以最快,是它在繪制簡單的二維圖形,或者開發(fā)簡單的二維項(xiàng)目的時(shí)候,具備主場優(yōu)勢(shì),因?yàn)閏anvas2d 本身就是為二維而生的。
wasm 的編譯和執(zhí)行速度快,我是深信不疑的,畢竟是Google出品。但它之所以比原生canvas2d 慢,我想它應(yīng)該還沒有發(fā)揮出自己的優(yōu)勢(shì),至于如何在二維項(xiàng)目中發(fā)揮其最大優(yōu)勢(shì),還有待研究。
WebGL 最慢的原因是它擅長GPU并行渲染,而在渲染簡單圖形的時(shí)候,因?yàn)樗咭恍?fù)雜邏輯,比如著色器與js間的數(shù)據(jù)傳輸,反而渲染速度要比原生canvas 慢很多很多。
總結(jié)
最后,我個(gè)人認(rèn)為,若只是開發(fā)簡單的二維項(xiàng)目,不涉及復(fù)雜的光柵化,或者大量的逐像素操作,直接使用原生canvas2d 開發(fā)即可,因?yàn)檫m合的才是最好的。
下一章,我會(huì)在逐像素操作方面,對(duì)比一下canvas2d、wasm和WebGL的渲染速度。