为 WordPress 加入 Server Timing 判断不同行为性能差异

b29692084bbb

自打上次为我的博客加入了 Redis 缓存后,博客站点访问速度明显变快,几乎可以达到秒开的效果。剩下的需要在网络层面进行进一步的优化。

不过,我还在思考如何才能更好的优化我的 WordPress 性能。很显然,我需要一个指标来帮助我做决策。这让我想到了一个东西 —— HTTP 标准中的 Server-Timing Header。

Server-Timing 标头传达在一个给定请求-响应周期中的一个或多个参数和描述。它用于在用户浏览器的开发工具或 PerformanceServerTiming (en-US) 接口中显示任何后端服务器定时参数(例如,数据库读/写、CPU 时间、文件系统访问等)。

来自 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Server-Timing

Server Timing 可以帮助我们记录服务端到底在哪些步骤中消耗了哪些时间,可以方便我进行性能的查询。

使用 WP Server Timing 添加 Server-Timing 头

我在 WordPress 的 Plugin Directory 目录进行了搜索,并没有找到支持这个功能的插件,不过我在 Github 上找到了这个插件 —— https://github.com/ocReaper/wp-server-timing

有了这个插件,我就可以无需自己手动添加相应的能力。

使用插件也非常简单,在页面上下载压缩包,并在 WordPress 后台安装并启用这个插件。

d2b5ca33bd970f64a6301fa75ae2eb22 14
安装后的效果

安装完成后,你接下来要做的就是重新在浏览器中打开你的网站,并按下 F12 打开开发者工具,选择文档 Tab(英文是 Document),刷新当前页面,就可以看到列表中出现了一个你博客地址对应的文档,点击文档,并在弹出的窗口中切换到「时间」Tab,就可以在下方看到服务器计时了。

d2b5ca33bd970f64a6301fa75ae2eb22 15
示意图

按照上图的结果,可以看到,我的 WordPress 耗时最长的是 Template Processing ,我需要针对这个属性进行定向优化。

辅助理解资料

以下是 WordPress 的加载顺序图,你可以对比着参考

dtckd
WordPres 的加载顺序图,来源:https://www.rarst.net/wordpress/wordpress-core-load/

WordPress 的静态化缓存和动态化缓存应该如何选择?

b29692084bbb

在我发出了 为 WordPress 加入 Redis 缓存提升访问性能 的文章后,有不少朋友给了建议,主要有以下几个:

  1. 可以在前面套一层 CDN ,使用 CDN 来完成缓存。
  2. 可以配置 Nginx 缓存。
  3. 可以给文章生成静态的。

在我看来,这些都是很好的建议,对于很多新人的博客主而言,都是不错的选择。不过就我自己的需求而言,这个并不是好的选择。

从网站性能的提升而言,他们所提供的建议确实是不错的,通过对网站进行静态化处理,从而实现访问的提速,用户直接访问静态的缓存是不错的选择。

不过,对于我来说,倒也不仅仅是给读者一个更加舒服的阅读体验,对于我自己而言,更加舒适的写作体验也是极为重要的。

引入了 Redis 作为缓存后,所有的 MySQL 查询会进行一定的缓存,从而让网站的整体使用体验变得更好,对于我来说,是一个更好的选择。

为 WordPress 加入 Redis 缓存优化访问性能

0dbb4980acb58d4396e9a2055bf2176e

在之前的文章我是如何优化博客的本站在用的一些WordPress插件中我提到,我是使用了 WP-Optimize这个插件来进行博客优化的。

d2b5ca33bd970f64a6301fa75ae2eb22 11
WP Optimize

WP-Optimize 为用户提供了开箱即用的缓存方式,可以将你的 WordPress 文章加入文件缓存,从而减少在 MySQL 中查询的次数。

不过,文件缓存的问题是性能受限于你所使用的磁盘,而我使用的是阿里云的标准云磁盘,性能一般,所以访问速度并不能算快。

过去在我还愿意折腾 WordPress 的时候,我是会在 WordPress 上加入一些别的缓存的,比如 Redis、Memcached。不过,随着时间的流逝,我折腾的意愿变得越来越弱,就远离了这些。

直到最近刚好有空,于是开始研究起了 Redis 缓存。

其实在古早时代(比如我刚开始折腾个人博客的时候,2012年),WordPress 的 Redis 功能并不是特别好用,需要自己手动下载 object-cache.php 放在对应目录中,然后修改配置文件手动来开启,甚至还需要替换掉 index.php 文件来让请求通过缓存进行。

这次的折腾,让我感受到,时代在进步,配置缓存也变得简单了许多。

Requirements

在这篇博客中我并不打算介绍 Redis Server 的安装和调试过程,你可以在搜索引擎中找到各种各样的教程引导你如何完成安装的过程,因此,请自行完成 Redis Server 的安装,后续的各项操作会默认你已经完成了 Redis Server 的安装调试。

需要注意的是,如果你不打算修改配置文件,则需要在安装 Redis 之后,设置为空密码。而空密码是不安全的,建议你通过 iptables、安全组策略等方式,屏蔽掉 6379 端口的外部请求,只允许本地请求。

安装 Redis 缓存

我这次安装 Redis 缓存选择了 Redis Object Cache 这个插件。

d2b5ca33bd970f64a6301fa75ae2eb22 12
Redis Object Cache

和你在别的网站上看到的教程相比,这个插件提供了一个可视化的查看和管理的方式,对于懒得手动操作和编辑代码的人来说,更加友好。

安装插件后,启用插件,你可以在设置中的「Redis」设置页面找到如下的界面:

d2b5ca33bd970f64a6301fa75ae2eb22 13
设置页面

点击 Enable Object Cache,就会开启 Redis 的 Object Cache 。

如果你已经在之前配置好了 Redis Server,则会直接看到如下左图的界面。但如果你的 Redis Server 还没有配置或配置了密码,就会显示如下右图的界面,就需要你检查你的 Redis Server 是否配置成功。

d2b5ca33bd970f64a6301fa75ae2eb22 15
配置成功的情况
d2b5ca33bd970f64a6301fa75ae2eb22 14
配置失败的情况

当你看到如上左图的界面后,就说明你已经开启了 Redis 的 Object Cache 了,后续涉及到文章内容、菜单等各项基本配置的查询时,会优先使用 Redis 的缓存,而不是查询 MySQL,从而降低了 MySQL 的查询压力,提升了查询的诉求。

至此,你的 Redis 就配置好了,可以打开你的网站首页,享受飞一样的速度。

d2b5ca33bd970f64a6301fa75ae2eb22 17
开启前的 TTFB 为 2.29 秒
d2b5ca33bd970f64a6301fa75ae2eb22 16
开启后的 TTFB 为 673.49 毫秒

FAQ

1. 如何使用非本地 Redis Server 或如何使用带密码鉴权的 Redis Server?

如果你需要使用非本地的 Redis Server(比如云 Redis),那么你需要在你的 wp-config.php 中加入如下代码来进行配置。

define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
// define( 'WP_REDIS_PASSWORD', 'secret' );
define( 'WP_REDIS_TIMEOUT', 1 );
Code language: JavaScript (javascript)

2. 如果我一个服务器上有多个 Redis ,如何配置使数据不会混淆呢?

有两种方式,

第一种方式是可以给你的不同站点配置不同的 Redis DB,只需要在你的 wp-config.php 文件中加入如下的配置,即可实现不同的站点使用不同的 Redis 数据库,你可以从 0 开始,向上递增设定不同的 Redis 数据库。

define( 'WP_REDIS_DATABASE', 0 );
Code language: JavaScript (javascript)

第二种方式是你无法控制 Redis,必须使用同一个数据库,那么你可以通过给其添加不同的 salt 来实现即使使用同一个数据库,数据也不会产生混淆。

define('WP_CACHE_KEY_SALT', 'www_ixiqin_com_');
Code language: JavaScript (javascript)

3. Metrics 怎么理解?

在 Redis 设置页面,你可以看到另外有一个 Metrics Tab,这个 Tab 你可以看到你的插件的工作情况,方便你随时进行查询 & Debug。

第一个 Time 是指 Redis Object Cache 和 Redis 沟通,获取数据所需的时间,可以看到,我这里的查询时间大概是在 12ms,耗时不多。需要注意,你第一次看可能会注意到,这里有一个 Object Cache Pro ,灰色的 Object Cache Pro 其实是官方在推广其自家的付费插件,付费插件 $99/月,可以提供更好的 Redis 查询性能。

d2b5ca33bd970f64a6301fa75ae2eb22 18

第二个 Bytes 则是 Redis Object Cache 从 Redis 获取到数据的大小,当有人访问你的文章的时候,这个数据就会出现一个增长,访问结束后就会消失。

d2b5ca33bd970f64a6301fa75ae2eb22 19

第三个 Ratio 则是缓存的命中率,基本上保持在 99% + ,说明缓存的命中率还不错。

d2b5ca33bd970f64a6301fa75ae2eb22 20

最后一个 Calls 则是调用次数,免费版不会批量获取数据,因此,调用次数会很高,而在付费版,会一次性拿多个数据,从而获得更少的查询次数。不过我目前对于这个速度已经很满意了,就不再购买付费的版本了。

d2b5ca33bd970f64a6301fa75ae2eb22 21

延展阅读