首屏优化核心是控制浏览器解析HTML时的资源调度节奏,关键在于避免同步阻塞行为;内联CSS须≤2–3KB以防TTFB升高,script需用defer/async而非无属性加载,preload字体必加crossorigin,首屏图片须设loading="eager"并带宽高属性,服务端应尽早flush骨架HTML。

首屏优化不是“加几个属性就完事”,而是要控制浏览器解析 HTML 时的资源调度节奏。真正卡住首屏的,几乎从来不是 HTML 文件本身大小,而是它触发的同步阻塞行为。
为什么内联 CSS 必须控制在 2–3KB 内
内联
- 超过 3KB 后,HTML 主文档传输时间显著上升,实测 TTFB 增加 100–400ms
- 服务端无法缓存内联样式,每次 HTML 变更都得重传全部 CSS,CDN 命中率归零
- Chrome Coverage 面板可验证:打开 DevTools → More Tools → Coverage → 刷新,红色未使用部分超 30% 就该清理
- 别手动提取:用
crtters(Vite 插件)或purgecss+html-webpack-plugin自动提取,输入是 HTML + CSS,输出是精准关键 CSS
script 标签放 head 还是 body 底部?关键看属性
放哪儿不重要,有没有对的属性才决定白屏与否。现代写法统一放 ,但必须带加载策略。
- 业务 JS(如 Vue mount、表单校验)→ 用
defer:下载异步,执行在 DOM 解析完成后、DOMContentLoaded前,且保持顺序 - 统计/埋点脚本(如
analytics.js)→ 用async:下载不阻塞,但执行时机不可控,需自行判断document.readyState - 绝对禁止:
<script src="app.js"></script>无属性写法,这是首屏白屏最常见原因 -
document.write()在现代浏览器中已废弃,执行即清空文档流,必然白屏重绘
preload 字体或图片时,crossorigin 是硬性要求
preload 不是“多下个文件”那么简单。字体若漏掉 crossorigin,浏览器会静默失败,连 Network 面板都看不到请求;图片若错配 as 类型,可能被降级为普通 GET,失去高优先级。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
- 字体必须写全:
<link rel="preload" href="inter.woff2" as="font" type="font/woff2" crossorigin>—— 缺crossorigin,字体不会加载 - 首屏 Hero 图可用:
<link rel="preload" href="hero.jpg" as="image">,但别对所有<img alt="HTML面试题首屏优化_html面试题首屏加载优化方案【解析】" >都加,否则抢带宽 - 别
preloadmain.js:它已被defer覆盖,重复调度等于浪费 - 验证是否生效:Chrome DevTools → Network → 找预加载资源 → 看 Priority 列是否为
high
loading="lazy" 对首屏图完全无效,还可能引发双加载
浏览器规范明确:位于视口内或紧邻下方的 <img alt="HTML面试题首屏优化_html面试题首屏加载优化方案【解析】" >,会忽略 loading="lazy" 并立即加载。但如果你没显式声明 loading="eager",某些旧版 Chrome 或 Safari 会 fallback 到 JS 懒加载逻辑,导致 src 被读两次。
- 首屏图片必须加
loading="eager",哪怕它是第一个<img alt="HTML面试题首屏优化_html面试题首屏加载优化方案【解析】" > - 所有
<img alt="HTML面试题首屏优化_html面试题首屏加载优化方案【解析】" >必须带width和height属性(不是 CSS),否则懒加载完成前高度为 0,造成 CLS 偏移 -
<picture></picture>中的<source></source>不支持loading,只在<img alt="HTML面试题首屏优化_html面试题首屏加载优化方案【解析】" >上设 - 兼容性兜底:
'loading' in HTMLImageElement.prototype判断是否原生支持,否则走IntersectionObserver
最容易被忽略的是服务端行为:哪怕 HTML 写得再规范,如果后端等所有数据聚合完才 flush 第一个字节,首屏就注定延迟。骨架 HTML 应在 开始后立刻输出,首屏数据通过 window.__INITIAL_DATA__ 注入,而非等客户端 fetch。


















