关键路径资源需在HTML解析阶段预设备用链路,关键CSS内联fallback须精简首屏规则、禁用@import和外部URL、置于link前;fetch关键JS应配AbortController在1500ms超时降级;离线包未就绪时通过localStorage读取版本匹配的压缩critical CSS。

关键路径资源不能只靠“加载失败再 fallback”,必须在 HTML 解析阶段就准备好备用链路——否则弱网下白屏时间会直接翻倍。
关键 CSS 加载失败时,内联 fallback 样式怎么写才有效
内联的 fallback 不是把整份 CSS 复制粘贴进去,而是仅保留影响首屏渲染的最小规则集(比如 body、.hero、h1 的 font-size 和 color),且必须满足三个条件:
- 不包含
@import—— 否则浏览器仍会发起同步请求,失去 fallback 意义 - 不依赖外部字体或图片 URL —— 所有
url()替换为系统字体或 base64 占位(如background: #f0f0f0) - 放在
<style>中,且位于所有<link rel="stylesheet">之前,确保它最先参与 CSSOM 构建
错误示例:<style>@import url('fallback.css');</style> —— 这等于没写。
fetch 关键 JS 时如何用 AbortController 触发降级逻辑
关键 JS(如初始化渲染器、路由入口)若超时未返回,不能等 onerror,因为弱网下请求常卡在 pending 状态不触发回调。必须主动中断并执行降级:
立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 超时阈值设为
1500ms,不是凭感觉;实测中 >800ms 响应延迟已显著拖慢 FCP - 中断后立即注入轻量 fallback 脚本,例如只挂载静态 DOM 或显示 skeleton,而非尝试重试
- AbortController 实例不能复用:每次 fetch 都要新建,否则
abort()可能失效
典型写法:const controller = new AbortController(); fetch('/app.js', { signal: controller.signal }).catch(() => injectFallback()); setTimeout(() => controller.abort(), 1500);
离线包未就绪时,如何让 HTML 直接读取本地缓存的 critical CSS
Service Worker 安装完成前,页面无法拦截请求,但 HTML 本身可以提前判断缓存是否存在并加载内联样式。关键点在于:
- 不要依赖
caches.has()—— SW 未激活时该 API 抛错;改用localStorage.getItem('critical-css-v2')存储提取后的关键 CSS 字符串 - 版本号必须与离线包一致,否则 fallback 样式与真实 DOM 结构错配(比如新版本加了
.card--new类,旧 CSS 里没有) - 注入时机必须在
<head>内尽早执行,最好在第一个<script>标签里,避免被后续样式覆盖
注意:localStorage 读取是同步的,但字符串过长(>50KB)会导致解析阻塞,务必压缩并剔除注释。
真正难的不是写 fallback,而是让 fallback 和主流程共用同一套 DOM 结构和 class 命名——否则降级后样式错乱、交互失效,比白屏更糟。


















