link rel="preload" 是提前加载关键图片的轻量方案,需指定 as="image" 和准确路径,配合 js image 加载与 load/error 监听,并确保 url 一致及 webp 等格式的 type 与服务端 content-type 匹配。

用 link rel="preload" 提前加载关键图片资源
浏览器默认按 HTML 解析顺序加载图片,<img> 标签出现在 DOM 中才开始请求。但游戏启动前就该把主角、UI 图标、场景贴图这些关键图片拿在手里,否则首帧卡顿、闪白、占位符明显。直接上 link rel="preload" 是最轻量、兼容性足够(Chrome 50+、Firefox 56+、Safari 11.1+、Edge 16+)的方案。
它不触发渲染,只提前发起 HTTP 请求并存入内存缓存,等真正 <img src="..."> 或 new Image().src = "..." 时直接复用,毫秒级命中。
- 必须指定
as="image",否则浏览器无法正确设置请求头(如Accept: image/webp)和缓存策略 - 路径必须准确——相对路径基于当前 HTML 的位置,不是 JS 所在目录;建议统一用根相对路径(
/assets/hero.png)避免歧义 - 不要滥用:只预加载首屏必现、体积大(>10KB)、且确定会在 1–2 秒内使用的图片;背景图、延迟加载的关卡资源不适合
- 如果图片带 CDN 参数(如
?v=2.1.0),预加载的 URL 必须完全一致,否则缓存不命中
JS 动态创建 Image 对象并监听 load 事件
预加载解决的是“网络拉取”,但游戏逻辑需要确认“图片已解码可用”。仅靠 link preload 无法得知何时能安全绘制——尤其在低端设备上,解码可能滞后。所以得配合 JS 主动加载 + 监听。
注意:不能只靠 link preload 就认为图片“已就绪”;也不能只用 new Image() 而跳过预加载,那样会重复请求。
- 先确保 HTML 中有对应
<link rel="preload" as="image" href="/assets/ui/button.png"> - 再在 JS 中创建实例:
const btnImg = new Image(); btnImg.src = "/assets/ui/button.png"; - 必须监听
load,而非onload属性赋值(易被覆盖);推荐用btnImg.addEventListener("load", handler) - 务必加
error监听:路径错、404、MIME 类型异常都会触发,否则资源缺失静默失败 - 如果图片需跨域(如 CDN 域名不同),必须设
btnImg.crossOrigin = "anonymous",否则 canvas 绘制时抛SecurityError
避免 link preload 和 Image 加载冲突导致双请求
现象:Network 面板看到同一张图发了两次请求,状态码一个是 200(from memory cache),另一个是 200(from disk cache)甚至 304——浪费带宽,还可能因并发限制造成排队延迟。
根本原因是 URL 字符串不完全一致:大小写、编码、尾部斜杠、查询参数顺序差异都会让浏览器视为不同资源。
- 检查预加载的
href和 JS 中Image.src是否逐字符相同(包括协议、域名、路径、参数) - 避免自动添加时间戳参数:Webpack/Vite 的
import.meta.env.BASE_URL或构建时 hash 插件生成的路径,要确保两端同步 - 服务端开启
Cache-Control: public, max-age=31536000并正确返回ETag或Last-Modified,让 304 协商缓存生效 - 开发期用 Chrome DevTools 的 “Disable cache” 模式测试真实首次加载行为,别信本地强缓存表现
WebP/AVIF 等现代格式的预加载要显式声明 type
浏览器不会根据文件扩展名或响应头自动选择最优格式预加载。如果你通过 <picture></picture> 切换 WebP,但预加载仍用 hero.png,那 WebP 版本根本不会进缓存,后续 <img> 还得重下。
解决方案是:预加载时用 type 属性明确告知 MIME 类型,让浏览器按支持情况选择对应资源。
- 服务端需对 WebP 文件返回
Content-Type: image/webp,否则type无效 - 写法示例:
<link rel="preload" as="image" href="/assets/hero.webp" type="image/webp"> - 可叠加多个
link标签分别预加载 PNG、WebP、AVIF,浏览器自动选第一个支持的;但注意增加请求数,建议只预加载 1–2 种主力格式 - 若用
fetch()+createObjectURL()方式加载,预加载的type不影响它,此时需 JS 侧自行判断格式支持并匹配 URL
type 和服务端 Content-Type 的配合。这两处出问题,预加载就等于没做。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











