必须紧贴开头,仅允许doctype和空白符;script应移至前或用defer/async;语义化标签和合理嵌套可加速解析;lazy加载仅适用于非首屏图片,且须设宽高防cls。

meta charset位置错,解析器直接重载
浏览器启动HTML解析时,默认用Latin-1读前1024字节;如果<meta charset="utf-8">没落在这个范围里,它会先按错误编码解析一部分,再发现声明、触发整页重载——中文乱码、脚本执行失败、首屏闪动全由此起。
必须紧贴开头,前面只允许和空白符(不含BOM)。注释、空行、<code><title></title>都算违规。
- 验证方法:
curl -s your-page.html | head -c 1024 | hexdump -C,确认charset字符串出现在输出中 - VS Code里开“显示不可见字符”,检查有没有隐藏BOM(UTF-8 with BOM是高频坑)
- 构建工具如Vite默认不加BOM,但某些编辑器保存时会偷偷加上
script阻塞DOM构建,白屏卡在解析阶段
遇到<script src="app.js"></script>,浏览器立刻暂停HTML解析,等下载+执行完才继续。这不是JS慢,是解析器被硬生生按了暂停键。
同步脚本一律移出,放到前是最稳妥的兜底方案。
- 业务主逻辑脚本:用
defer,保证DOM解析完再执行,且保持顺序 - 统计/广告类脚本:用
async,但确认它不查document.getElementById等DOM节点 - 绝对禁用
document.write()——本地双击打开时直接清空整个文档流
语义化标签不是为了好看,是给解析器走捷径
<header></header>、<nav></nav>、<main></main>这些标签在Chromium和WebKit源码里有专用解析分支,而<div class="header">会被当普通容器处理,多走CSS类匹配、JS查询等通用流程。
<p>深层嵌套(>6层)的<code><div>会让解析器反复递归,拖慢DOM树生成速度。
<ul>
<li>替换掉无意义的包裹层,比如<code><div><div><div><p>内容</p></div></div></div>
<section></section>不能乱替<div>:它代表可独立分发的内容单元(如一篇博客正文),不是样式占位符
<li>Flexbox/Grid布局能天然减少嵌套,比浮动或表格布局更利于解析器线性推进</li>
<h3>loading="lazy"加错地方,LCP反而更差</h3>
<p>原生懒加载只对<code><img>和<iframe></iframe>生效,且默认触发距离视口约1250px。全量加,关键图片就被压后加载,LCP指标直接拉垮。
Hero图、轮播首帧、按钮图标这类首屏强依赖元素,必须删掉loading="lazy"。
- 必须显式设置
width和height属性,否则会引发CLS(布局偏移) - 不要用
<picture></picture>包着loading="lazy"再套<source></source>——部分旧版Chrome不识别,降级为同步加载 - 服务端渲染场景下,首屏图片建议直接内联
src,别靠JS动态注入
<script></script>里——它们不会报错,但会让浏览器多跑几百毫秒。











