<link> 的 onload 事件在对应资源下载完成且成功解析(如 CSS 注入、字体解码)后触发,是单个资源自身的加载终点,与 window.onload 无关;仅 rel="stylesheet"、rel="preload"(as 值合法且匹配 MIME)、rel="modulepreload" 等支持,而 prefetch 等不支持。

<link> 的 onload 事件触发时机
<link> 标签的 onload 事件在对应资源**下载完成且成功解析(如 CSS 已加载并生效、字体已可渲染)后立即触发**,但不等待其下游依赖(比如 @import 的 CSS、字体中引用的 SVG glyphs)。
它不是“页面级”信号,而是**单个 <link> 资源自身的加载生命周期终点**。例如:
-
<link rel="stylesheet" href="main.css">:onload在 CSS 文件下载完成、解析完毕、样式规则注入 DOM 后触发(此时document.styleSheets已包含该表) -
<link rel="preload" as="font" href="font.woff2" crossorigin>:onload在字体文件下载并解码成功后触发(注意必须带crossorigin,否则 Chrome/Safari 不会触发) -
<link rel="prefetch" href="next.js">:onload**不会触发**——prefetch不支持onload,它没有标准事件回调机制
<link> 的 onload 和 window.onload 完全无关
<link onload="handler()"> 是元素级事件,和 window.onload 毫无关系。后者要等整个页面所有资源(含图片、iframe、未声明 async/defer 的脚本)都加载完才触发。
常见误用场景:
立即学习“前端免费学习笔记(深入)”;
- 在
<link rel="stylesheet">的onload里调用getComputedStyle(document.body),期望拿到新样式——可能失败,因为样式虽已加载,但重排(reflow)尚未发生,需加requestAnimationFrame延迟一帧 - 监听
<link rel="preload" as="script">的onload,然后立刻eval()或import()——不行,preload只是预取,不执行;得配合fetch()+createScript或动态import() - 省略
as属性或写错(如as="fonts"而非as="font"),导致浏览器降级为普通 fetch,onload仍会触发,但时机不可控、优先级丢失
哪些 <link> 类型实际支持 onload
根据当前主流浏览器(Chrome 128+、Firefox 127+、Safari 17.6+)行为,只有以下 rel 值的 <link> 元素能可靠触发 onload:
-
rel="stylesheet":最稳定,CSS 加载完成即触发 -
rel="preload"(且as值合法):支持script、style、font、image、audio、video等,但as="font"必须配crossorigin -
rel="modulepreload":ESM 预加载,onload在模块图解析完成(非执行)后触发
rel="prefetch"、rel="dns-prefetch"、rel="preconnect" 均不支持 onload ——它们没有资源加载完成的概念,只是提示浏览器做底层优化。
容易被忽略的跨域与 MIME 类型陷阱
<link> 的 onload 触发前提是资源**HTTP 状态码为 2xx 且 MIME 类型匹配 as 声明**。否则会静默失败或触发 onerror:
- 同源
<link rel="stylesheet" href="/a.css">返回text/plain→ 不触发onload,也不报错,样式无效 -
as="font"但服务端没返回Access-Control-Allow-Origin: *或没设crossorigin属性 → 字体加载失败,onload不触发,控制台可能只显示 FOIT(Flash of Invisible Text) -
as="script"但响应头是Content-Type: application/json→ Chrome 直接忽略 preload,onload永远不触发
调试时务必检查 Network 面板中的 Initiator 列,确认请求是否真走的是 preload 路径,而非 fallback fetch。



















