应删减冗余div嵌套、启用img/iframe的loading="lazy"、内联关键css并预加载非关键css、压缩html及开启gzip/brotli。

删掉那些没用的 <div> 嵌套<p>浏览器解析 DOM 是从上到下逐层构建的,每多一层 <code><div> 就多一次节点创建和样式计算。实际项目里常见这种写法:<pre class="brush:php;toolbar:false;"><div class="wrapper">
<div class="container">
<div class="content">
<p>正文</p>
</div>
</div>
</div></pre>
<p>它既没语义,又拖慢解析。换成语义化标签后,DOM 更扁平,CSS 选择器也更轻量:</p>
<pre class="brush:php;toolbar:false;"><main><p>正文</p>
</main></pre>
<ul><li>优先用 <code><header></header>、<nav></nav>、<main></main>、<section></section>、<aside></aside> 替代纯 <div>
<li>避免“div 套 div 套 div”——超过 3 层嵌套就要警惕</li>
<li>开发时保留结构注释没问题,但上线前必须删掉所有 <code><!-- ... -->
图片不加 loading="lazy" 就是默认全量加载
loading="lazy" 就是默认全量加载未设置 loading 属性的 <img> 标签,浏览器会一上来就发起全部请求,哪怕图片在屏幕外几屏远。这直接拖慢首屏时间,还浪费用户流量。
只需加一个属性就能解决:
@@##@@
-
loading="lazy"是原生支持,Chrome 76+、Firefox 75+、Safari 15.4+ 都可用,不用额外 JS 库 - 首屏关键图(比如 banner、logo)要显式设
loading="eager"或干脆不设,确保立即加载 - 对
<iframe></iframe>同样适用:<iframe src="..." loading="lazy"></iframe> - 注意:如果页面高度靠 JS 动态撑开(比如 Vue/React 懒加载内容),
loading="lazy"可能失效,得配合IntersectionObserver
关键 CSS 内联,其余用 rel="preload" 提前取
浏览器渲染页面前必须拿到首屏所需的 CSS,如果这个 CSS 在外部文件里,就得再发一次 HTTP 请求——哪怕只有几十 KB,也会造成几百毫秒白屏。
把首屏用到的 CSS 提取出来,直接塞进 里:
<style>
.hero { margin: 0; font-size: 2rem; }
.btn { display: inline-block; padding: 8px 16px; }
</style>
- 内联 CSS 总大小建议控制在 14KB 以内(gzip 后),否则反而阻塞渲染
- 非关键 CSS 改用
<link rel="preload" as="style" href="non-critical.css">,让浏览器提前 fetch,但不立即执行 - 别用
@import引入 CSS——它会串行加载,比<link>多一轮 RTT - 如果用了构建工具(如 Vite/Webpack),可用插件自动提取 critical CSS,不用手抠
HTML 文件本身不压缩,相当于裸奔上传
开发时写的 HTML 充满缩进、空行、注释,看着舒服,但上线后这些字符全是带宽和解析负担。一个 20KB 的 HTML 文件,去掉空白后可能只剩 12KB —— 节省 40% 传输量。
- 用
html-minifier(CLI 或 Webpack 插件)做构建时压缩,不是手动删空格 - 服务端必须开 Gzip 或 Brotli 压缩:Nginx 配
gzip on;,Apache 开mod_deflate - 检查响应头是否有
Content-Encoding: gzip,没有就是没生效 - 别依赖 CDN 自动压缩——有些 CDN 对 HTML 默认不压缩,得手动开启
真正卡顿的网页,问题往往不在 JS 多复杂,而在 HTML 结构松散、资源加载无序、文件体积放任自流。精简不是为了“代码好看”,而是让浏览器少走一步、少等一次、少算一遍。











