link 标签必须放在 中,否则会导致 FOUC、阻塞脚本执行;critical CSS 应内联,non-critical 用 media="print" 异步加载;preload 适用于确定即将使用的 CSS,prefetch 不可用于当前页样式;PostCSS 插件顺序影响输出稳定性。

为什么 link 标签必须放在 里
浏览器解析 HTML 是自上而下流式进行的,link 如果写在 底部,CSS 文件会延迟加载,导致页面先“无样式”渲染(FOUC),尤其在弱网或大屏设备上更明显。部分浏览器(如旧版 Safari)甚至会阻塞后续脚本执行,直到该 link 加载完成。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 所有
必须位于内,且尽量靠前(早于) - 避免使用
@import在 CSS 文件中引入其他样式 —— 它会引发串行加载,破坏并行下载能力 - 若需动态加载(如主题切换),改用
document.createElement('link')+onload回调,而非插入到 body 中
如何区分 critical 与 non-critical CSS
首屏内容所需的样式叫 critical CSS,其余(如模态框、折叠面板、打印样式)属于 non-critical。混在一起加载,会拖慢首次内容绘制(FCP)。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 用工具(如
critters或penthouse)提取首屏关键 CSS,内联到的中 - 剩余样式通过
实现异步加载(注意:需配onload降级逻辑) - 禁止在
non-critical.css中覆盖critical已声明的字体、颜色、间距等基础变量,否则易引发重绘抖动
preload 和 prefetch 在 CSS 加载中的实际效果差异
preload 是高优先级资源预加载,强制浏览器立即获取;prefetch 是低优先级预取,仅在空闲时进行。对 CSS 而言,误用 prefetch 会导致样式加载被严重推迟。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 仅对「确定即将用到」的 CSS(如单页应用中下一个路由的样式)使用
,并配合onload切换media - 绝对不要用
prefetch加载当前页所需 CSS —— 它不会提升 FCP,反而可能挤占带宽 - 检查 Network 面板中
Initiator列:若发现 CSS 显示为Other或Parser,说明未被正确预加载,需核查as属性是否为style
PostCSS 插件链顺序为什么影响最终输出
PostCSS 是线性处理流程,插件顺序直接决定 CSS 变换结果。例如 postcss-preset-env 若放在 cssnano 后面,会导致自定义属性(--color-primary)被压缩丢弃,而 postcss-import 放错位置则引发路径解析失败。
推荐最小可行顺序(基于 postcss.config.js):
module.exports = {
plugins: [
'postcss-import', // 第一:处理 @import
'postcss-preset-env', // 第二:转译新语法(:is(), logical props)
'postcss-custom-properties', // 显式控制变量处理时机
'cssnano' // 最后:压缩(避免提前删掉待替换的变量)
]
}
容易踩的坑:
- 把
autoprefixer放在postcss-preset-env前面,会导致部分新特性无法加前缀(如gap在 flex 容器中) -
开发环境禁用
cssnano,但忘了关掉postcss-preset-env的stage: 3以上特性,造成本地能跑、CI 构建报错
link 位置约束、以及明确区分 critical/non-critical 的拆分逻辑,比追求“最短加载时间”更能减少线上样式异常。










