<script>放在<head>中会阻塞DOM构建,浏览器必须下载、解析并执行脚本后才继续解析HTML,导致首屏白屏;同步脚本尤其危险,document.write()甚至会清空文档。

HTML 本身不执行逻辑,但它是整个页面加载和渲染的起点——写法稍有不当,首屏就卡住,后续 JS/CSS 可能压根没机会执行。
为什么 <script> 放在 <head> 里会让页面白屏?
浏览器解析 HTML 是自上而下流式进行的。一旦遇到没有 async 或 defer 的 <script> 标签,会立刻暂停 DOM 构建,去下载、解析、执行脚本,等它完事才继续。首屏内容还没来得及生成,用户就看到白屏。
- 同步脚本必须等执行完才恢复 HTML 解析,哪怕只是 10KB 的空文件
-
document.write()更危险:它会清空当前文档,强制重置解析器 - 第三方统计、广告脚本最容易偷偷加同步
<script>,要逐个检查
async 和 defer 到底该选哪个?
二者都解除阻塞,但执行时机完全不同,选错会导致 JS 报错或功能失效。
-
async:下载不阻塞 HTML,但一下载完就立即执行(可能早于 DOM 构建完成),适合完全独立的脚本,比如埋点、广告 -
defer:下载不阻塞 HTML,执行则等到整个 HTML 解析完毕、DOM 树构建完成之后,且按出现顺序执行,适合依赖 DOM 的主业务逻辑 - 多个
defer脚本会按顺序执行;多个async脚本执行顺序不确定 - 注意:
async/defer对内联脚本无效,只对带src的外部脚本起作用
图片懒加载怎么写才不翻车?
loading="lazy" 是最轻量的懒加载方案,但滥用或漏配关键属性,反而会拖慢首屏、破坏布局稳定性。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
立即学习“前端免费学习笔记(深入)”;
- 首屏图片必须用
loading="eager"或干脆不写该属性,否则 LCP(最大内容绘制)指标直线下跌 - 所有
loading="lazy"的<img>必须带width和height属性,否则滚动时会触发 CLS(累积布局偏移) -
<iframe>也支持loading="lazy",但仅在 Chromium 内核中稳定生效,Safari 需额外 polyfill - 服务端渲染(SSR)场景下,若首屏图片由 JS 动态插入,
loading属性可能被忽略,得配合 IntersectionObserver 手动控制
哪些 HTML 写法会悄悄拖慢解析速度?
浏览器解析 HTML 不是“越短越好”,而是“结构越清晰、标签越语义、嵌套越浅”,解析越快。很多看似无害的写法,实际在增加 DOM 构建开销。
- 深层嵌套的
<div>(比如<div><div><div>...</div></div></div>)会让 DOM 树节点数激增,影响内存与遍历性能 - 用
<table>做布局,或大量float+clear,会触发浏览器更复杂的布局计算路径 - 缺失
<meta charset="utf-8">或把它放在<title>后面,会导致浏览器反复重读 HTML,重新解析编码 - 在
<head>里放大段内联 JS/CSS,虽避免请求,但会延长 HTML 解析时间,且无法被缓存
真正影响 HTML 加载速度的,往往不是某一行代码,而是你没意识到的“默认行为”——比如浏览器对某个属性的隐式处理、对缺失尺寸的回退策略、对未声明编码的猜测过程。这些细节在开发时看不见,却在用户手机上放大成明显的卡顿。


















