fetch & createImageBitmap 加速图片在 Canvas中渲染

117 阅读1分钟

利用 fetch + createImageBitmap 开启ThreadPoolForegroundWorker, 减少 ImageDecode 时间, 最终加速图片在 canvas 中的渲染.

问题

首先来看一张 performance recording 的截图

具体场景:  canvas 渲染多张图片时的 performance 的表现

可见在将近 2s 的时间里, 几乎有一半时间都耗费在了 Image Decode 上, 而且他们都是按顺序调用, 没有并行.

ImageDecode 是什么? 

ImageDecode 是图片解码的一个阶段,用于将下载的图片数据转换为可用于渲染的位图。

这样看来这一步是必须要做的.

像这样计算压力比较大的场景,  能否利用 worker 来解决呢? 

使用 createImageBitmap 来加速解码

上面提到了可以利用 worker 来加速,  Chrome 50+ 后有 createImageBitmap 接口,  Chrome 在调用这个 API 的时候本身会利用 ThreadPoolForegroundWorkers 并发执行.  

developer.chrome.com/blog/create…

ThreadPool

来自图形界大神 Greggman 的帖子
webglfundamentals.org/webgl/lesso…

最终效果

做了一个对比测试,  分为 3 中情况. 原始办法就是直接在 image onload  事件中绘制到 canvas 上,  方法1 是 img.onload + createImageBitmap 处理后再绘制到 canvas 中,  方法2 这是 fetch 和 createImageBitmap 结合后再绘制到 canvas 上. 

最终对比效果如下

可见,  createImageBitmap 在 fetch 配合使用后, 能在 ThreadPoolForegroundWorker 中运行.

从耗时来看, 方法2 加载同样多的图片耗时大大减少.

代码

gist.github.com/lumixraku/6…