HTML首屏加载慢主因是关键路径资源阻塞,应为script加defer或async、内联关键CSS、首屏图片preload且禁用lazy、非首屏图片加lazy并设宽高。

HTML 页面首屏加载慢,八成不是代码“写得丑”,而是关键路径上某处 <link rel="stylesheet"> 或 <script> 没加对属性、放错位置,或内联了不该内联的东西——代码质量在这里直接翻译为浏览器执行路径的确定性。
为什么没加 defer 的 <script> 是质量硬伤
没属性的 <script src="app.js"> 会强制浏览器暂停 HTML 解析,等 JS 下载 + 执行完才继续。这不是“慢一点”,是白屏卡死,用户根本看不到任何内容。
- 业务脚本(如初始化 Vue 实例、绑定表单事件)必须用
defer:下载不阻塞,执行时机在 DOM 构建完成后、DOMContentLoaded前,且严格按书写顺序 - 统计类脚本(如
analytics.js)可用async,但别和业务脚本混写在一个<script>标签里——顺序失控就可能操作不到 DOM -
type="module"默认等效于defer,还支持静态分析,但 Safari 14.1 以下不支持,上线前得查兼容性 - 绝对禁用
document.write():现代浏览器执行即清空整个文档流,不可逆,本地调试时尤其容易当场崩溃
<style> 内联多少才算“质量过关”
内联 CSS 不是“越多越好”,而是“刚好够首屏渲染”。超量内联会让 HTML 文件体积暴涨,TTFB(首字节时间)反而变长,尤其在弱网或高延迟环境下更明显。
- 关键 CSS 范围很窄:只含首屏像素生成必需的选择器,比如
.header、.hero-banner、按钮基础尺寸与颜色,不含折叠区、弹窗、分页栏样式 - 体积建议 ≤ 10KB(gzip 后 4–8KB),超过可能触发 TCP 初始拥塞窗口限制,多一个 RTT
- 别在内联
<style>里写@import:它会发起额外请求,彻底破坏内联意义 - 内联后,对应外链
<link rel="stylesheet">必须删掉,否则样式重复应用,可能引发意外交互(比如 hover 效果叠加两次)
loading="lazy" 加在 <img> 上为什么反而拉低 CLS
原生懒加载不是“所有图片都该加”,加错会导致布局偏移(CLS),直接拖垮 Core Web Vitals 分数,这是代码逻辑缺陷,不是配置疏忽。
立即学习“前端免费学习笔记(深入)”;
- 首屏 Hero 图、轮播第一张、关键按钮图标必须去掉
loading="lazy",确保立即加载 - 每个加了
loading="lazy"的<img>必须显式设width和height,否则浏览器无法预留空间,加载时重排布局 - 别同时写
src和loading="lazy",再用 JS 监听IntersectionObserver—— 浏览器可能先加载src,造成重复请求 - Safari 15.4+ 才支持
loading="lazy"对<iframe>的支持;旧版安卓 WebView 可能完全忽略,需降级方案
<link rel="preload"> 写错比不写更糟
preload 是高优先级提示,不是“提前加载所有东西”的开关。写错会抢带宽、挤掉 HTML 或关键 CSS,属于典型的“优化反噬”。
- 只对当前导航中「立刻要用」的资源生效:关键字体(
as="font"+crossorigin必加)、首屏 Hero 图(as="image")、极少数核心 JS 入口 -
as属性必须准确:写成as="fetch"或漏掉,优先级降为 low,等于白加;as="style"才能让预加载的 CSS 被后续<link rel="stylesheet">复用 - 别对
main.js或整个vendor.jspreload——它已被defer覆盖,再 preload 属于冗余调度 - 验证是否生效:打开 Chrome DevTools → Network 面板,看预加载资源的
Priority是否为high;若出现警告 “The resource … was preloaded using link preload but not used within a few seconds”,说明资源没被真实使用
真正影响首屏性能的,从来不是 class 名有没有语义化、缩进用四个空格还是 tab——而是每一处 <script> 属性、<link> 的 media 值、<img> 的 width/height 是否被当成“必须填的字段”来对待。这些细节不靠 lint 工具报错,全靠开发者对浏览器关键路径的理解是否扎实。



















