首屏加载慢的根本原因是关键路径资源阻塞渲染,优化需让关键资源尽早可用、非关键资源不抢道、无关资源不进场;关键资源包括首屏HTML、必需CSS和同步JS,可通过Chrome Coverage与Performance面板识别;关键CSS应内联(≤10KB)并移除外链,非关键CSS异步加载;非首屏JS用defer或async,禁用document.write();preload仅用于当前导航必用资源,首屏图禁用lazy。

首屏加载慢,根本原因不是代码写得不够“漂亮”,而是关键路径资源在阻塞渲染——浏览器必须等它们就绪才能画出第一帧。优化的核心,是让关键资源尽早可用、非关键资源不抢道、无关资源不进场。
识别哪些资源属于关键路径
关键路径资源是指浏览器生成渲染树前必须完成加载与解析的资源,主要包括:
- 首屏HTML结构本身:尤其是导航栏、Banner、主标题等可见内容所在的DOM节点
-
首屏必需的CSS:能决定这些节点是否显示、如何布局、什么颜色的样式规则(比如
display: block、font-size、background-color) -
同步执行的JS:位于
<head>中未加defer或async的脚本,会暂停HTML解析并立即执行
用 Chrome DevTools 的 Coverage 面板(More Tools → Coverage)刷新页面,能直观看到每个 CSS 文件里有多少比例实际被用到;红色越少,说明越接近“关键”。再配合 Performance 面板看 Parse HTML → Recalculate Style 是否长时间等待某项资源,就能定位瓶颈。
关键CSS要快且轻:内联 + 条件加载
CSS 是默认阻塞渲染的资源,不能让它拖后腿:
- 把首屏真正需要的 CSS 提取出来,内联进
<head>的<style>标签中,体积控制在 ≤10KB;超过这个大小,HTML 文件传输反而变慢 - 内联后,记得删掉对应外链的
<link rel="stylesheet">,否则样式重复应用可能引发意外交互 - 非首屏样式(如弹窗、分页、底部)不要放在主 CSS 里,可改用
<link rel="preload" as="style" href="non-critical.css" onload="this.rel='stylesheet'">异步加载,或用media="print"或media="(min-width: 768px)"让浏览器跳过初始渲染阻塞 - 绝对禁用
@import:它强制串行加载,会把多个 CSS 文件变成排队等位
JS执行不能打断渲染流
JS 可以读写 DOM 和 CSSOM,所以浏览器默认会暂停解析 HTML,等 JS 下载、解析、执行完再继续——这是常见白屏元凶:
- 所有非首屏必需的 JS(如统计、分享、埋点)统一加
defer(保证顺序、不阻塞解析)或async(完全异步、无序执行) - 首屏必须执行的 JS(比如轮播初始化),优先考虑是否能转为纯 CSS 实现;若不可替代,确保它体积小、逻辑简,并放在
<body>底部 - 彻底禁用
document.write():它会清空当前文档重来,现代浏览器已将其标记为高危操作
资源加载时机要“懂业务”而不是“堆标签”
不是所有 preload 都合理,也不是所有 prefetch 都有用:
-
preload只用于「当前导航立刻要用」的资源:首屏字体、关键 CSS、核心 JS。必须带as属性(如as="style"),否则浏览器无法正确预分配资源类型 - 别对 logo.svg 用
prefetch——它是首屏关键图像,应内联或preload as="image" - 别在
<head>里preload一个 2MB 的打包文件——它会抢占带宽,挤掉真正该优先的 CSS 和字体 - 图片统一加
loading="lazy",但首屏图要保留src直接加载,避免懒加载导致首屏空白


















