预加载文章插图只有两种可靠方式:一是用在中声明首屏关键图,必须写as="image"、用静态路径、推荐根路径;二是用new image()动态预加载条件性图片,需先绑定事件再赋值src,并处理缓存命中情况。

预加载文章插图,核心就两条路:link rel="preload" 声明关键图,或用 new Image() 控制运行时加载。别指望 loading="lazy" 或 display: none 的 <img> 能预加载——它们只会拖慢首屏。
用 link rel="preload" 预加载首屏插图
这是最干净、最可控的方式,适用于你明确知道哪些插图会出现在首屏(比如文章顶部 banner、主配图、作者头像)的场景。
-
as="image"必须写,漏了浏览器就当普通资源 fetch,不走图片缓存和解码逻辑 - 必须放在
里,越早越好;动态插入无效 -
href只能是静态路径,不能含 JS 变量、模板语法,比如href="/assets/${slug}.webp"会直接 404 - 相对路径按 HTML 文档位置解析,不是按当前 JS 文件位置;推荐用根路径(
/images/cover.jpg)避免歧义 - Chrome 101+ 可加
fetchpriority="high"提升请求优先级,旧版忽略无副作用
示例:
<link rel="preload" as="image" href="/images/article-cover.webp" fetchpriority="high"><link rel="preload" as="image" href="/images/author-avatar.png">
用 new Image() 预加载条件性插图
适合需要逻辑判断的场景:比如用户滚动到某段落才预载下一张图、根据 window.devicePixelRatio 加载 @2x 版本、或等用户 hover 某个按钮后再加载详情图。
- 必须先绑定
onload/onerror,再赋值src;否则缓存命中时事件同步触发,回调直接跳过 - 要检查
img.complete === true,如果为真,说明已缓存,需立刻执行成功逻辑 - 不要在循环里密集
new Image()—— 浏览器并发请求数通常卡在 6~8 个,建议用 Promise 队列控并发(例如每次最多 3 个) - 别写
new Image().src = url这种简写,失败无法捕获,也无法 await
基础封装示例:
const preloadImage = (url) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => reject(new Error(`Failed to load ${url}`));
img.src = url;
});
};
千万别把懒加载当预加载用
这是最常踩的坑:给插图加 loading="lazy",还配了个 link rel="preload",结果浏览器一边拼命提前拉图,一边又等滚动到前 500px 才渲染——白忙活。
-
loading="eager"是默认行为,显式写出来只是“不懒”,不等于“提前” -
decoding="async"只影响解码时机(防主线程卡顿),和下载完全无关 -
<img src="..." style="max-width:90%">或 CSSbackground-image+ 负偏移,本质是“让浏览器顺手加载”,但没优先级、不可监听、可能被延迟,不算真正预加载 - WebP 预加载必须带 fallback:
link只负责下载,实际<img>渲染时仍需srcset或<picture></picture>兜底
复杂点在于:预加载本身不解决渲染时机,它只确保资源进缓存。真正让插图“秒出”,还得配合尺寸声明(width/height 或 aspect-ratio)、格式选择(WebP/AVIF)、以及服务端缓存策略。漏掉任意一环,预加载都可能白做。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











