首屏内容快速呈现取决于HTML节点构建顺序和资源加载时机。CSS需用<link>并行加载而非@import串行阻塞;脚本应加defer/async避免阻塞解析;首屏图片显式设loading="eager"且位置靠前;HTML物理顺序决定DOM构建快慢。

首屏内容能否快速呈现,不取决于你写了多少 CSS 或 JS,而取决于浏览器解析 HTML 时,哪些节点先被构建、哪些资源被优先请求。结构顺序 + 加载时机必须对齐渲染机制,否则优化全是白忙。
为什么 <link rel="stylesheet"> 必须放 <head> 里,但不能含 @import
@import 是串行阻塞加载器:浏览器必须下载并解析完主 CSS 文件,才能发起被 import 的文件请求。比如 main.css 里写两行 @import,实际是「下载 main.css → 解析 → 请求 reset.css → 等它回来 → 再请求 layout.css」,无法并发。
- 改用多个
<link rel="stylesheet">并行加载,浏览器可同时发请求 - 老项目中执行
grep -r "@import" src/,尤其注意node_modules里第三方 CSS 是否偷偷带了它 - 主题切换等条件加载逻辑,用 JS 动态创建
<link>,别用@import模拟
<script> 放 </body> 前 ≠ 不阻塞,关键看有没有 defer
没加任何属性的外部 <script src="app.js">,哪怕放在 </body> 前,下载阶段仍会暂停 HTML 解析——尤其在弱网下,用户看到的是白屏,不是内容闪一下再消失。
-
defer:下载异步,执行在 DOM 解析完成后、DOMContentLoaded前,多个脚本按书写顺序执行 -
async:下载异步,下载完立刻执行,不等 DOM,也不保证顺序,适合统计、广告等无依赖脚本 - 内联脚本(
<script>console.log(1)</script>)一定阻塞,除非加defer或async - 千万别在
<head>里放没加defer/async的外部<script>,尤其别塞在<link rel="stylesheet">前——这会让 CSSOM 构建卡住
首屏图片必须显式设 loading="eager",且 HTML 位置靠前
loading 属性只对 <img> 和 <iframe> 生效,它不改变网络请求优先级,但严格控制“何时发起请求”。设为 lazy 的图,即使出现在 HTML 第一行,也不会在解析时触发 HTTP 请求。
立即学习“前端免费学习笔记(深入)”;
- 首屏大图、Banner 图:显式加
loading="eager",防止被浏览器启发式策略误判为非关键资源 - 折叠区域、滚动才出现的卡片图:用
loading="lazy",且确保它们在 HTML 中位置靠后 - 不要混用:同一页面既有
loading="eager"又有loading="lazy"的图片时,靠前的lazy图可能比靠后的eager图更晚开始加载 -
loading对 CSS 背景图、srcset、<picture>无效,别指望它起作用
最容易被忽略的点是:HTML 标签的物理顺序决定 DOM 构建快慢,而不是 CSS 视觉位置。把侧边栏或广告位写在 <main> 前面,首屏主内容 DOM 就得等它们解析完才能生成——再 fancy 的 flex-order 也救不回来。



















