首屏脚本应按依赖关系选择async或defer属性:不依赖DOM用async,依赖DOM但不依赖其他脚本用defer,关键同步脚本需内联且极小;首屏图片禁用lazy,非首屏才启用并设宽高;仅内联首屏必需CSS并压缩;HTML结构应扁平、首屏内容靠近body开头。

script放哪儿最不卡首屏
脚本位置直接决定首屏是否白屏——浏览器解析到 <script> 就停,直到下载、执行完才继续。把所有 <script src="xxx"></script> 手动拖到 </body> 底部,是过时且不可靠的做法。
现代最优解是按依赖关系选属性:
- 完全不依赖 DOM 的脚本(如埋点、广告 SDK):用
async,下载不阻塞,执行也不保证顺序 - 依赖 DOM 但不依赖其他脚本(如轮播图初始化):用
defer,下载并行,执行在 DOM 解析完后、DOMContentLoaded前,且严格按书写顺序 - 必须同步执行、且影响首屏结构的脚本(极少见):内联 +
type="module",或确保体积极小、无网络请求
注意:SSR 场景下 defer 比 async 更稳妥,避免 JS 执行时 DOM 还没就绪。
首屏图片加 loading="lazy" 反而更慢?
加了 loading="lazy" 却拉低 LCP,常见于三个误用:
立即学习“前端免费学习笔记(深入)”;
- 首屏图片也加了该属性:浏览器跳过加载,关键图延迟出现,LCP 暴涨
- 没写
width和height:图片尺寸未知,触发布局重排(CLS) - SSR 渲染后 JS 动态插入的
<img>:默认loading="eager",和预期不符
稳妥做法:首屏图片不加 loading 属性(等价于 eager),非首屏统一加 loading="lazy",且所有 <img> 都带明确宽高——哪怕用 CSS aspect-ratio fallback 兜底。
内联 CSS 到底内联多少?
内联不是越多越好。浏览器只有拿到完整的 CSSOM 才能生成渲染树,外部 CSS 文件哪怕只有 2KB,网络往返也常耗 100–300ms。把首屏必需的样式内联进 <head> 的 <style>,等于跳过一次网络请求。
但别内联整站 CSS:
- 只取「渲染首屏 DOM 节点所必需」的部分,可用工具如
PurgeCSS或手动生成 critical CSS - 内联后必须压缩:去掉空格、注释、重复规则,避免内联本身增大 HTML 体积
- 配合
media属性做条件加载,比如<style media="(max-width: 768px)">只在小屏生效,大屏不会解析
HTML 结构怎么写才不拖慢解析
浏览器解析 HTML 是自上而下流式进行的,遇到阻塞型资源就停住——所以结构顺序直接决定首屏时间。深层嵌套、冗余容器、错位资源标签,都会放大解析开销。
实操要点:
-
<main>、<section>等承载首屏内容的标签尽量靠近<body>开头,避免前置大量导航、广告、埋点脚本 - 控制嵌套深度在 3–4 层以内;超 5 层
<div>包裹就该被质疑必要性 - 删掉所有
display: none但仍在 DOM 里的冗余节点——它们不参与渲染树,但会占用 DOM 解析和内存 - 慎用
<table>布局:table-layout: fixed可强制浏览器秒定列宽,否则扫描全部单元格内容才能确定宽度
真正影响性能的不是语义是否“正确”,而是浏览器构建 DOM 树、匹配样式、计算布局时多做了多少无谓工作——结构越直白,解析越快,重排越少。



















