主题性能:defer、合并、懒加载

作者: admin 分类: wordpress主题制作教程 发布时间: 2026-11-06 18:53

先把”性能”拆成三个问题

一说优化性能,很多人第一反应是”上缓存插件””换 CDN””压缩图片”。这些都对,但顺序容易搞错。

我把主题能管的部分拆成三个问题,按影响从大到小排:

  1. 阻塞:浏览器为了等你一个文件,整页都不渲染;
  2. 体积:下载的东西太大;
  3. 请求数:要来回太多次。

这三个里,第一个影响最大——因为它是”卡住”,不是”慢一点”。

第一件事:把阻塞的脚本挪开

我原来的 header.php 是这样的:

<head>
  <link rel="stylesheet" href=".../bootstrap.min.css">
  <link rel="stylesheet" href=".../style.css">
  <script src=".../jquery.min.js"></script>
  <script src=".../bootstrap.min.js"></script>
</head>

那两个 <script> 干了一件坏事:浏览器读到它们,会停下来下载、停下来执行,然后才继续往下解析 HTML。

你在手机上打开这个页面,看到的顺序是:白屏 → 下载 jQuery(几十 KB)→ 执行 → 下载 bootstrap → 执行 → 才开始画页面。

用户在前一秒多里看到的是白的。

改法很简单,加一个属性:

<script defer src=".../jquery.min.js"></script>
<script defer src=".../bootstrap.min.js"></script>

defer 的意思是:”你可以先下载,但别急着执行,等 HTML 解析完了再按顺序执行。”

这一改,浏览器就能一边下载脚本、一边继续解析页面,首屏不再等它。

defer 和 async,别用错

两个属性长得像,作用完全不同:

属性 下载 执行时机 适合什么
不加 立即,阻塞解析 下载完立刻 几乎没有
async 并行,不阻塞 下载完就执行,顺序不定 完全独立的统计、广告脚本
defer 并行,不阻塞 HTML 解析完,按书写顺序 有依赖关系的库(jQuery → 插件)

关键区别:async 不保证顺序,defer 保证顺序。

我的 bootstrap 依赖 jQuery,如果两个都用 async,有可能 bootstrap 先下载完先执行——那时 $ 还不存在,控制台报错「$ is not defined」,整个交互全废。

所以:有依赖的,一律用 defer。

但 defer 有一个副作用,必须验证

这个问题我踩过。

脚本改成 defer 之后,它执行的时间点变成了”HTML 解析完之后”。如果页面里有一段内联脚本,在 HTML 中间就调用了 $(...),那它执行的时候 jQuery 还没到,直接报错。

我改完之后干的第一件事,是打开手机点了一下汉堡菜单。

为什么要专门测这个?因为那个菜单的展开靠 bootstrap 的 JS。如果脚本没加载成功,菜单按钮点了没反应——而桌面端看不出问题(桌面端菜单是横向展开的,不依赖 JS)。

测的时候一定要用手机,或者把浏览器窗口拉窄。

如果真出问题,两个解法:

  • 把依赖它的那段内联脚本,也改成 defer 或者挪到页面底部;
  • 退一步,只给 jQuery 加 defer,把 bootstrap 放回原位。

第二件事:图片,别用 2560px 的图显示 560px

我另一个站上有个真实的例子:一张封面图,原图 2560×2560,334 KB。而它在页面上显示的宽度是 560px。

多下载了 4 倍多的像素,用户一点都看不出来。

WordPress 上传图片时会自动生成多个尺寸(thumbnail / medium / large),主题要做的是用对尺寸,而不是永远用原图。

三个具体做法:

一、用 the_post_thumbnail() 而不是自己拼 <img>

<?php the_post_thumbnail( 'medium', array( 'loading' => 'lazy' ) ); ?>

传 'medium',WordPress 就会自动输出 srcset(一组不同宽度的候选图),浏览器按自己的屏幕宽度挑一个。这一行代码,比手动压缩一百张图都管用。

二、首屏之外的图加 loading="lazy"

<img src="..." alt="..." loading="lazy">

浏览器会等图片快进入视口了才开始下载。文章页正文里的图,全都该加。

三、首屏那张图别加 lazy

这条容易被忽略:lazy 是”推迟加载”,而首屏图是”马上就要看”的。给它加 lazy,等于让浏览器先犹豫一下再下载,反而更慢。

首屏图要么不加,要么用 fetchpriority="high" 提示浏览器优先下载。

第三件事:请求数,能少一个是一个

每多一个文件,就多一次”请求—等待—响应”的往返。移动网络下,一次往返可能就是 100 毫秒。

主题层面能做的:

  • 合并 CSS:把小文件的样式并进 style.css;
  • 别加载用不上的库:我原来 head 里加载了整套 bootstrap,实际只用了栅格和几个组件;
  • 该删的删:WordPress 默认会往 head 里塞一些东西(emoji 脚本、区块库样式),用不上的直接 remove_action 掉。

最后这条我实测过:清理前首页 gzip 后 9930 字节,清理后 7953 字节,降了 20%。而且清理掉的东西(区块库 18.5 KB)里,我一个字都没用过。

还有一个几乎零成本的东西:dns-prefetch

<link rel="dns-prefetch" href="//hm.baidu.com">

这行告诉浏览器:”我等下可能会连这个域名,你可以先把域名解析做了。”

它只省几十毫秒,但成本是一行代码。凡是页面里会加载的第三方域名,都值得加一行。

别做的事

三个常见但没好处的”优化”:

  1. 把 CSS 写成内联。省了一次请求,但每个页面都重复一遍,还破坏了缓存。除非那份 CSS 只有几百字节;
  2. 为了”加载快”把图片压到糊。手机卡套餐站的海报糊了,用户看不清资费,等于白做;
  3. 装一堆”优化插件”。每个插件自己也要加载,还可能互相打架。我自己只用了一个缓存插件。

小结

一句话记住:先解阻塞(defer),再减体积(图片尺寸),最后减请求(删无用资源)。顺序反了,效果差一半。

下一篇聊缓存——为什么你改完代码,访客看到的还是旧的。

本系列导航

相关文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Powered by 草根站长笔记 © 2015-2026 草根站长笔记 Inc.版权所有,禁止转载