最轻量兼容的异步css加载方式是,利用浏览器对不匹配媒体类型的低优先级处理实现异步下载,onload中必须立即切换media并清空onload防止重复触发。

直接用 link 标签加 media="print" 是最轻量、兼容性最好、且真正不阻塞首屏的方案;rel="preload" 必须配合 onload 切换 rel 值才有效,否则只是白下个文件。
用 media="print" 让浏览器跳过初始解析
浏览器遇到 <link rel="stylesheet"> 就会阻塞 HTML 解析和首次渲染,直到 CSSOM 构建完成。但如果你把 media 设成当前不匹配的值(比如 "print"),浏览器就把它当非关键资源处理,既下载又不阻塞。
-
media="all"或media="screen"和没设一样,照样阻塞,必须确保初始不匹配 - 插入后不能立刻读
link.sheet—— 它大概率是null,得等link.onload触发后才能安全访问 - IE 不支持
onload,要 fallback 到onreadystatechange;Safari 的onload也不稳定,建议加 5s 超时兜底 - 激活时机选
DOMContentLoaded后立即切回media="all",比window.onload更早、更合理
用 rel="preload" + onload 切换必须写对
rel="preload" 单独存在等于没用:它只发起请求、存缓存,完全不参与 CSSOM 构建,页面不会有任何样式变化。
- 必须同时满足三个条件:
rel="preload"+as="style"+onload中把rel改成"stylesheet" -
this.onload = null要写在回调最开头,防止 SPA 路由复用或刷新时重复执行报错 - IE 完全不支持
rel="preload",必须用<noscript></noscript>包一层降级的<link rel="stylesheet"> - 如果 CSS 文件里含
@font-face或大图,这些子资源会在挂载后才拉取,可能挤占首屏带宽 —— 得检查非关键 CSS 内部是否藏了渲染阻塞项
动态插入前必须查重 href,否则会重复加载
多次调用加载函数(比如组件反复挂载)时,document.head.appendChild(link) 会不断插入新 <link>,导致重复请求、样式冲突甚至内存泄漏。
- 用
document.querySelector(<code>`link[href="${href}"]`)判断是否已存在 —— 注意路径需完全一致,"theme.css"和"./theme.css"被视为不同资源 - 带版本号如
"theme.css?v=2"应允许重新加载,此时不能简单按href全等判断,建议提取主路径做归一化 - 卸载时若需清理,别只靠
href字符串去querySelector删除 —— 可能误删其他组件引入的同名 CSS;稳妥做法是把创建的link存为组件级引用,卸载时调用link.remove()
真正容易被忽略的不是“怎么加”,而是“加完之后能不能立刻用”——onload 触发前读 sheet、查 getComputedStyle、操作 cssRules,十有八九失败或返回空。这个时间差不是靠 setTimeout 硬等能解决的,得靠事件驱动逻辑落地。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











