<link>加载快因并行下载且支持media/preload,@import需等待宿主CSS解析后才发起请求,导致首屏阻塞;动态插入@import无效,且不入document.styleSheets。

为什么加载快,而@import会拖慢首屏
浏览器解析 HTML 时,遇到 <link rel="stylesheet"> 立即发起请求,并与其他 <link> 并行下载;@import 必须等它所在的 CSS 文件(无论是外部 .css 还是内联 <style>)完整下载并开始解析后,才启动被导入资源的请求。
常见错误现象:PageSpeed Insights 报 “Render-blocking resources”,但你只写了 1 个 <link>?大概率是它引入的 CSS 里嵌了多层 @import,把关键样式拖慢 2–3 秒。
实测:3 层嵌套 @import 在弱网下比等效 <link> 多出 800ms+ 首屏阻塞时间。
media 和 preload 能力差异直接决定优化上限
<link> 支持 media 和 rel="preload",@import 完全不支持。
立即学习“前端免费学习笔记(深入)”;
media 属性能让浏览器跳过不匹配条件的下载(比如 media="print" 的样式在屏幕浏览时根本不发请求);@import url("mobile.css") screen and (max-width: 768px) 这种写法语法看似合理,但无效——mobile.css 仍会被无条件下载,只是不应用规则,浪费带宽。
rel="preload" as="style" 可提前拉取高优先级 CSS,但需配合 JS 切换 rel 值才能生效,例如:onload="this.rel='stylesheet'";仅靠 preload 不会应用样式。
运行时动态加载只能用 link,@import 无法注入
主题切换、A/B 测试、按需加载组件样式等场景,必须用 <link> 实现。
以下写法不生效:
const style = document.createElement('style');
style.innerHTML = '@import url("theme-dark.css");';
document.head.appendChild(style);
原因:浏览器忽略运行时动态插入的 @import 规则,它只在 CSS 文件首次解析时起作用。
可行方式只有创建 <link> 元素:document.createElement('link') + appendChild,浏览器立刻发起请求并应用样式。
最容易被忽略的一点:document.styleSheets 不包含 @import 加载的样式
<link> 加载的样式表会立刻出现在 document.styleSheets 中,而 @import 导入的样式不会——这意味着你想用 JS 检测是否加载完成,根本没法可靠监听。
另外,相同选择器下,<link> 引入的样式优先级高于 @import 引入的样式;IE6–IE8 对 @import 位置敏感(必须在文件最顶部),否则可能被忽略。



















