关键阻塞资源不消除,首屏就卡在白屏——根本原因是<link rel="stylesheet">和同步<script>主动中断HTML解析与绘制;内联关键CSS必须且仅限首屏真实用到的选择器(≤10KB),禁用@import以防退化为同步阻塞;defer适用于依赖DOM的主逻辑,async仅用于无序独立脚本;非关键CSS应通过media="print"+onload延迟激活,避免FOUC;验证需以DevTools Performance和Network面板真实链路为准,重点关注Parse HTML后是否出现长空白段。

关键阻塞资源不消除,首屏就卡在白屏——不是代码写得慢,是浏览器被你写的 <link rel="stylesheet"> 和 <script> 主动拦下了。
为什么内联关键 CSS 必须做,且不能靠 @import 补救
浏览器解析 HTML 时,遇到 <link rel="stylesheet"> 就暂停 DOM 构建,等 CSSOM 完成才继续;而 @import 在 CSS 文件里再拉一次 CSS,是串行、不可并行、无法被 preload 捕获的二次阻塞。实测多一个 @import 平均拖慢 FCP 300ms+。
- 内联范围只取首屏真实用到的选择器:比如
.hero、.logo、.submit-btn的尺寸、颜色、显示逻辑,别把整个main.css塞进去 - 体积控制在 ≤10KB(实测超过 1KB 就开始影响 TTFB,尤其弱网下)
- 绝对不用
@import包关键样式——它会让内联失效,退化为同步网络请求 - 构建阶段用
critters(Vite)或critical(Webpack)自动提取,但上线前必须人工验证:打开 DevTools → Elements → 检查首屏元素是否真有对应样式生效
script 标签加 defer 还是 async?看它要不要操作 DOM
defer 和 async 都解除 HTML 解析阻塞,但执行时机和顺序约束完全不同。错配会导致 document.getElementById 找不到节点、样式未就绪就执行动画、甚至脚本静默失败。
- 业务主逻辑(如初始化 Vue 实例、渲染首屏卡片列表)→ 用
defer:<script src="app.js" defer>,下载并行,执行在 DOM 解析完后、DOMContentLoaded前,且按书写顺序 - 无 DOM 依赖的独立脚本(如
analytics.js、广告 SDK)→ 可用async,但多个async脚本执行顺序不确定,别让它改全局状态 - 千万别留默认的
<script src="xxx.js">—— 它就是白屏元凶,DevTools Network 面板 Initiator 列显示parser就是它 - 兜底放
</body>前只是兼容旧项目,现代构建流程中defer更可控、更易调试
非关键 CSS 怎么延迟加载又不触发 FOUC
直接删掉非关键 <link> 不现实,但放着又阻塞渲染。正确做法是让它“不参与初始 CSSOM 构建”,等首屏绘制完成后再加载——关键是用 media 属性骗过解析器,再用 onload 激活。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
- 推荐写法:
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">,初始media="print"让浏览器忽略它,不阻塞;加载完立刻切回all - 保底方案加
<noscript><link rel="stylesheet" href="non-critical.css"></noscript>,防 JS 失效 - 别用
rel="preload" as="style"后手动appendChild—— 它仍会触发 CSSOM 重建,可能造成 FOUC 或样式闪动 - 媒体查询条件加载(如暗色模式)直接写
media="(prefers-color-scheme: dark)",别包在@import里
怎么确认你真的消除了 Render-Blocking
别信构建日志,要拿 DevTools 看真实链路。优化后如果 FCP 还 > 1s,大概率是某处漏掉了隐式阻塞点。
- Performance 面板录制加载过程,重点看
Parse HTML后是否紧跟着长空白段,再跳到Recalculate Style或Layout—— 空白段起点就是阻塞源 - Network 面板筛选
css和js,看Initiator列:显示parser的资源必须处理,显示other或script的可暂缓 - 检查所有
<img>是否写了width/height或aspect-ratio—— 尺寸缺失导致布局重排,也会延长 FCP - 第三方脚本(字体、地图、埋点)哪怕加了
async,也要确认它们没在内部document.write或同步拉资源 —— 这类脚本常静默阻塞,需单独禁用测试
最易被忽略的是:CSS 文件里的 @import、JS 中动态创建的 <link>、以及 SSR 页面里 JS 插入的图片没带 loading="eager" —— 它们不在 HTML 源码里,却一样卡住渲染树生成。

















