rel="icon" 不需 preload,浏览器自动早加载;仅需一行 <link rel="icon" href="/favicon.svg"> 放 head 开头,推荐 SVG;动态主题图标才需 JS 预加载。

rel="icon" 是浏览器自动处理的,不需要、也不该用 preload 预加载图标。
link rel="icon" 就够了,别加 preload
浏览器在解析 <head> 时,只要看到 <link rel="icon" href="/favicon.ico">,就会立即发起请求——时机足够早,体积足够小(通常 < 4KB),根本不需要额外干预。
常见错误包括:
- 在
<head>里同时写<link rel="icon">和<link rel="preload" as="image" href="/favicon.ico">,导致 Chrome 发两次请求 - 把图标路径写成相对路径(如
./favicon.png),而 HTML 文件在子目录下,结果 404 - 误以为
prefetch能加速图标加载,其实它对rel="icon"完全无效,浏览器直接忽略
正确写法只有一行,且必须放在 <head> 开头附近:
立即学习“前端免费学习笔记(深入)”;
<link rel="icon" href="/favicon.svg">支持
.ico、.png、.svg,推荐用 .svg(体积小、缩放无损)。
唯一需要主动预加载图标的场景:动态主题图标
当你的网站支持深色/浅色主题切换,且图标是 JS 动态注入(比如根据 prefers-color-scheme 切换 /icon-dark.svg / /icon-light.svg),这时浏览器无法提前知道该拉哪个,就得手动预加载。
操作要点:
- 先判断当前主题,再用
new Image()触发加载 - 必须先绑定
onload/onerror,再赋值src - 检查
img.complete:为true表示已缓存,可立刻应用 - 不要批量 new Image(),同域并发请求数有限(通常 6~8 个)
示例:
const preloadThemeIcon = (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;
});
};
<p>// 根据当前 scheme 决定预加载哪个
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
preloadThemeIcon('/icon-dark.svg');
} else {
preloadThemeIcon('/icon-light.svg');
}
loading="lazy" 和 display: none 对图标毫无意义
图标不是普通 <img>,不参与布局流,也不受懒加载控制。给 <link rel="icon"> 加任何属性(比如 loading="lazy")都会被浏览器忽略。
如果你发现图标“迟迟不显示”,大概率是:
-
href路径错误或返回 404 - 服务器没配好 MIME 类型(
image/svg+xml或image/x-icon) - 使用了非标准路径(如通过 JS 拼接 URL 后再 setAttribute),导致浏览器无法静态发现
真正影响图标加载速度的,从来不是“怎么预加载”,而是“路径对不对”和“服务器响不响应”。



















