图片懒加载结合canvas绘制的核心是视口检测后异步加载并安全绘制:用intersectionobserver监听data-canvas-src图片可见性,创建跨域image对象,在onload中确保complete为true后drawimage;失败时降级处理,无canvas或observer时回退为img标签或滚动检测。

图片懒加载结合 Canvas 绘制,核心是:等图片进入视口后再加载,加载完成再用 drawImage 渲染到 canvas 上,避免页面初始化时大量请求和阻塞渲染。
监听图片是否进入视口
使用 IntersectionObserver 判断图片元素(如 <img data-canvas-src="...">)是否可见,比滚动事件更高效、兼容性好(现代浏览器均支持)。
- 为每个待懒加载的图片创建 observer 实例,或复用一个全局实例
- 触发回调时,读取
data-canvas-src属性获取真实图片地址 - 记录该图片是否已开始加载,防止重复触发
加载图片并绘制到 canvas
图片加载成功后,不能直接用 img.src 赋值就绘图——需确保 img.complete === true 且尺寸可用,否则 drawImage 可能无声失败。
- 创建
Image对象,设置crossOrigin = "anonymous"(若图片跨域,否则 canvas 会污染,无法导出) - 在
img.onload中调用ctx.drawImage(img, x, y, width, height) - 可选:提前设置 canvas 宽高匹配图片自然尺寸,或按需缩放
处理 canvas 多图叠加与性能
多个懒加载图片依次绘制时,注意顺序和重绘逻辑,避免闪烁或错位。
- 给每张图片绑定唯一标识(如
data-id),绘制前校验是否仍需显示(DOM 可能已被移除) - 若需动态更新(如滚动中重新定位),建议先
ctx.clearRect()再重绘,或仅重绘变化区域 - 高频绘制场景下,可用
requestAnimationFrame聚合绘制,减少帧率抖动
降级与错误处理
网络异常、404 或 CORS 拒绝时,应有 fallback 行为,保障体验不中断。
- 监听
img.onerror,绘制占位色块或文字提示(如ctx.fillText("加载失败", x, y)) - 无 IntersectionObserver 时,退化为 scroll + getBoundingClientRect 判断(注意节流)
- canvas 不支持时,回退为普通
<img>标签显示











