@import 会阻塞页面渲染,因其强制浏览器等待引入的 CSS 下载解析完毕才继续构建 CSSOM;而 link 标签通过预加载器实现并行下载,不阻塞解析与渲染。

@import 为什么会让页面渲染卡住
因为浏览器必须等它引入的 CSS 完全下载、解析完,才能继续处理当前样式表里后面的规则,更别说开始渲染页面了。这不是“慢一点”,而是硬性阻塞——哪怕只有一行 @import url("reset.css"),整个 CSSOM 构建就会停在那儿,DOM 解析也可能被间接拖住。
常见错误现象包括:DOMContentLoaded 延迟、首屏白屏或 FOUC(无样式内容闪烁)、Lighthouse 报 “Eliminate render-blocking resources”。如果你在 Network 面板看到 CSS 请求的 Initiator 是 stylesheet 而不是 parser,基本就能确认是 @import 在链式触发。
link 标签怎么实现并行加载
<link rel="stylesheet" href="reset.css"> 这种写法,浏览器在 HTML 解析第一行时就通过预加载器(preload scanner)发现了它,立刻发起请求。多个 <link> 会同时启动下载,不排队、不等待。
实操要点:
立即学习“前端免费学习笔记(深入)”;
- 把所有被
@import引入的文件(比如reset.css、utils.css)抽出来,不再让主 CSS 文件引用它们 - 在 HTML 的
<head>中按依赖顺序写多个<link>,例如:reset.css必须在main.css之前 - 不要用 JS 动态插入
<link>来“模拟” @import——这绕过了预加载器,反而更慢
@import 和 link 的 media 属性行为差异
@import url("print.css") print; 看似能条件加载,但实际仍会阻塞主样式表解析;而 <link rel="stylesheet" href="print.css" media="print"> 会被浏览器识别为非关键资源,完全不参与渲染阻塞,且支持预解析。
可安全用于懒加载的场景:
-
media="print":打印样式,永不阻塞屏幕渲染 -
media="(prefers-color-scheme: dark)":暗色主题,匹配时才加载 -
media="(min-width: 768px)":仅在中大屏生效,小屏设备跳过请求
注意:media 不是给主样式表用的——关键 CSS 别加,否则可能直接不生效。
构建工具里 @import 没消失?可能是编译没走对路
Webpack/Vite 默认会把 Sass/Less 的 @import 在构建期内联或拆成 <link>,但如果你发现打包后 CSS 文件里还有 @import,大概率是配置出了问题:
- Sass 用户检查是否误关了
api: 'modern',导致降级为 CSS 原生 @import - Vite 用户确认没有在
css.preprocessorOptions.sass里禁用import处理 - 用了
mini-css-extract-plugin却把样式打进了 JS bundle?那@import就真变成运行时阻塞了
最稳的做法:删掉源码里所有 CSS 文件中的 @import,改用 JS 侧 import "./reset.css",交给构建工具统一管理加载时机。


















