Canvas存储ImageData后使用滤镜绘制卡顿如何解决?
Canvas绘制卡顿问题:原因及解决方法
问题现象
当内存中存储大量变量时,Canvas会变得非常卡顿。原本计划将ImageData保存到数组中(toDataURL处理Canvas阴影时会产生伪影),但发现这种存储方式会导致绘制速度大幅下降,尤其是使用blur这类Canvas滤镜时。虽然滤镜本身会减慢绘制速度,但内存中是否存储变量的差异非常显著,且在blur效果下差异更明显。另外,数组中存储100步数据和2步数据的影响差异并不大。
核心疑问:是否因为blur这类Canvas效果需要占用大量内存?如何正确解决卡顿问题?
复现代码
import "./styles.css"; const canvas = document.querySelector("canvas"); const ctx = canvas.getContext("2d"); canvas.width = 1000; canvas.height = 1000; canvas.style.width = "1000px"; canvas.style.height = "1000px"; const drawButton = document.querySelector(".draw"); const fillHistoryButton = document.querySelector(".fillHistory"); const history = []; const draw = () => { ctx.filter = "blur(5px)"; for (let i = 0; i < 200; i++) { ctx.beginPath(); console.log(i); ctx.arc( canvas.width * Math.random(), canvas.height * Math.random(), 4, 0, 2 * Math.PI ); ctx.fill(); } }; const fillHistory = () => { for (let i = 0; i < 2; i++) { console.log(i, "adding to history"); history.push(ctx.getImageData(0, 0, canvas.width, canvas.height)); } }; drawButton.addEventListener("click", draw); fillHistoryButton.addEventListener("click", fillHistory);
点击fill history按钮后,绘制操作会变得非常缓慢。
问题根源与解决方案
根源分析
卡顿并非源于内存中存储大量变量或getImageData方法本身速度慢,而是因为getImageData会触发Canvas从GPU渲染模式切换到CPU渲染模式,且浏览器不会主动切换回GPU模式。CPU绘制本身速度远低于GPU,尤其是在使用blur这类需要大量计算的滤镜时,性能差距会被进一步放大。
解决方案
使用Offscreen Canvas。Offscreen Canvas不会因调用getImageData而切换到CPU运行,始终保持GPU加速,因此能维持流畅的绘制性能。
内容的提问来源于stack exchange,提问作者Rostys
相关产品推荐
相关产品推荐

