link 立即并行加载,@import 串行依赖导致 fouc;link 可被 js 控制、支持 media/preload/server push,@import 无法静态分析、无扩展性、应慎用。

link 和 @import 的加载时机完全不同
浏览器一解析到 <link rel="stylesheet"> 就立刻发起请求,并行下载;而 @import 是 CSS 解析器的行为,必须等它所在的 CSS 文件(比如 main.css)下载并开始解析后,才触发导入请求——这是串行依赖。
常见错误现象:
- 页面 HTML 已渲染出文字,但样式空白 200–400ms 后突然“闪”一下 → 这就是 FOUC(Flash of Unstyled Content)
- 嵌套写法:
@import url("a.css");里再@import url("b.css");→ 两步串行,首屏时间直接翻倍 - 把
@import写在<style></style>块中间或底部 → 上方规则已生效,下方导入的样式覆盖不及时,局部错乱
DOM 操作和构建工具根本没法管 @import
<link> 是 DOM 节点,能被 JS 完全控制;@import 是 CSS 解析阶段的内部行为,JS 拿不到、改不了、监听不了。
这意味着你做不到这些事:
- 调用
document.styleSheets查看所有样式表时,@import加载的不会出现在列表里(只算“子样式表”,需递归cssRules访问,且时机不可靠) - 动态切换主题:
themeLink.disabled = true行得通,但对@import导入的部分完全无效 - Webpack/Vite 等构建工具无法静态分析
@import路径 → tree-shaking 失效、热更新漏文件、preload 提示缺失
link 支持 media、preload、rel 等关键能力,@import 几乎没有扩展性
<link> 可通过属性精细控制行为,@import 语法死板,只支持两种写法:@import url("x.css") 或加 media 查询,连缓存 bust(如 ?v=2.1)都要手动拼,稍有分号缺失就整条规则失效。
典型可用能力:
- 响应式加载:
<link rel="stylesheet" href="print.css" media="print"> - 提前拉取关键 CSS:
<link rel="preload" href="critical.css" as="style" onload="this.rel='stylesheet'"> - DNS 预解析、HTTP/2 Server Push 都只认
<link>,@import全部绕过
@import 在纯 CSS 文件里也该慎用
技术上允许,但现代项目基本不该用。它只在两种场景下勉强成立:维护老版 Bootstrap 这类遗留 CSS 库,或极小项目中做逻辑分块(如 @import "vars.css";)。问题在于:@import 是运行时请求,不是编译期合并 —— 很多人混淆了 Sass/Less 的 @import 和原生 CSS 的 @import。
哪怕只是 @import url("print.css") print;,也会阻塞屏幕样式渲染;HTTP/2 Server Push 对它无效;Lighthouse 等性能工具一律标为“潜在渲染阻塞”。
最容易被忽略的一点:你在 <style></style> 里写 @import,看起来只是换种写法,其实已经把样式加载逻辑从 HTML 解析阶段,拖到了 CSS 解析阶段 —— 渲染流水线被硬生生打断了一次。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











