利用 fetch + createImageBitmap 开启ThreadPoolForegroundWorker, 减少 ImageDecode 时间, 最终加速图片在 canvas 中的渲染.
问题
首先来看一张 performance recording 的截图
具体场景: canvas 渲染多张图片时的 performance 的表现
可见在将近 2s 的时间里, 几乎有一半时间都耗费在了 Image Decode 上, 而且他们都是按顺序调用, 没有并行.
ImageDecode 是什么?
ImageDecode 是图片解码的一个阶段,用于将下载的图片数据转换为可用于渲染的位图。
这样看来这一步是必须要做的.
像这样计算压力比较大的场景, 能否利用 worker 来解决呢?
使用 createImageBitmap 来加速解码
上面提到了可以利用 worker 来加速, Chrome 50+ 后有 createImageBitmap 接口, Chrome 在调用这个 API 的时候本身会利用 ThreadPoolForegroundWorkers 并发执行.
ThreadPool
来自图形界大神 Greggman 的帖子
webglfundamentals.org/webgl/lesso…
最终效果
做了一个对比测试, 分为 3 中情况. 原始办法就是直接在 image onload 事件中绘制到 canvas 上, 方法1 是 img.onload + createImageBitmap 处理后再绘制到 canvas 中, 方法2 这是 fetch 和 createImageBitmap 结合后再绘制到 canvas 上.
最终对比效果如下
可见, createImageBitmap 在 fetch 配合使用后, 能在 ThreadPoolForegroundWorker 中运行.
从耗时来看, 方法2 加载同样多的图片耗时大大减少.