WordPress 手动提速 – 缓存优化

由于大多数的 wordpress 博客都架设在与他人共享的虚拟主机上,所以速度和优化便成了 blogger 们经久不哀的话题。为了优化,我也看过不少的文章。看来看去,很多人只是老调重弹地讲了 WP Super Cache 插件;以及有些空泛地提出要去除不必要插件、优化 javascript 等,可惜这只说明了方向问题却没有点明该如何朝这个方向去做。只好依自己生平所学,手动地折腾了一把 WordPress 优化。

服务器端缓存机制

虚拟主机用户一般无法更改服务器的配置,我们也就不能在这方面有很大的期望。不过“缓存”这一手段仍然是一种相对可行的底层优化方法。Wordpress 有众多的缓存插件来支持这一行为,包括 WP Cache、WP Super Cache、DB Cache 等。

WP Cache 和 WP Super Cache 这样的插件通过生成 HTML 静态页面来降低服务器负荷,达到提速的目的。我个人却不太喜欢这样的方式。其原因有:一,这样做会丧失动态网站的灵活性。特别是那些根据客户端不同会作出不同响应的功能。比如我的主题中有一个 is_bot() 函数,用来针对搜索引擎的机器人作出一些 SEO 的调整。一旦我启用了静态缓存插件,便丧失了这种灵活性。有人说这些功能可以改成 Javascript 实现,但真要改动起来也比较麻烦,有些得不偿失。二,某些个人博客的瓶颈并不在PHP执行这个环节,而是客户与服务器之间的网络线路。甚至我认为,个人博客没有上万的 PV 完全没有必要采用静态化的策略。

DB Cache 插件我觉得可以试试,因为它的原理是缓存数据库查询,特别是虚拟主机中数据库服务器不是本机(localhost)时,这个插件会提高响应速度。但必须注意的一点是很多虚拟主机对于每用户可占用的内存是有限制的,如果这个值太低,那么这个插件也不太适用。

把缓存交给用户

与其在服务器上费力地设置缓存,更好的办法其实是“把缓存交给用户”。我用 Firebug + Yslow 分析自己博客的时候,发现它提示我的博客没有给静态内容设置缓存。于是用 cURL 连接到网站上通过观察 HTTP Header 来分析了缓存的机制。我的博客上 Apache 会发送“Last-modified”和“E-Tag” Header,这似乎也是大多数博客虚拟主机的配置。这样浏览器在请求的时候会发出“If-modified-since”请求,让服务器判断请求的内容(比如图片)是否在某个时间(通常是浏览器缓存的时间)以后发生变化。如果没有变化,服务器返回 HTTP 304 Not Modified 响应,浏览器则可以放心地使用本地缓存,从而降低了 HTTP 请求开销。

Yslow 建议给静态内容设置一个“永久”的缓存。这个永久通常是设置一年甚至更长的缓存期来实现的。设置缓存以后,服务器在对请求作出响应的时候会附加一个 Expires Header,告诉浏览器这个东西在多长时间内不会过期。这样浏览器就可以放心地使用缓存,甚至连 If-modified-since 请求和一个 HTTP 304 响应也不必要了。这样就大大地节省了在网络上的开销。访问者只是在第一次访问时会请求动态内容,接下来则会直接使用缓存的内容,达到了“把缓存交给用户”的目的。

实现方法

要做到这个也是件很容易的事情,对于 Apache 服务器来说,使用 mod_expire 就能轻松地设置缓存期。在 .htaccess 文件中加入以下内容:


# 启用缓存机制
ExpiresActive On

# 图片缓存时间为 1 年
ExpiresByType image/gif "now plus 1 year"
ExpiresByType image/jpeg "now plus 1 year"
ExpiresByType image/x-icon "now plus 1 year"
ExpiresByType image/png "now plus 1 year"

# Javascript, CSS 缓存时间为 12 小时
ExpiresByType text/css "now plus 12 hours"
ExpiresByType text/javascript "now plus 12 hours"
ExpiresByType application/javascript "now plus 12 hours"

有人要说,如果我的内容改变了怎么办呢?因为这样设置以后浏览器并不会向服务器询问是否有新的内容,而是老老实实地相信自己的缓存内容了。
如果你的改动是少数的几个图片,那么只需要在图片的 URL 后面自己加上一个任意的 query string 即可。比如说原来的图片 URL 是

http://blog.xiaoding.org/wordpress/wp-includes/images/smilies/icon_smile.gif

现在只需要在原地址后面加上一个 query 参数即可,此参数对于静态内容可以任意构造,我此处写的是 AnyQueryString

http://blog.xiaoding.org/wordpress/wp-includes/images/smilies/icon_smile.gif?AnyQueryString

这样浏览器会认为此时的图片与原来的不同,将再一次下载它。于是我们就达到了更新的目的。

WordPress 与 Qzone 和 Live Space 同步

背景及插件介绍

很多人倾心于 WordPress 博客平台的灵活性和可定制性,跑到 WordPress 中来写文章。但这样的话,文章一般只在由评论、Trackback/Pingback 等构成的博客圈内有影响,我们在 QQ、MSN 等即时通讯工具上的朋友就很难看到文章了(大多数人还不会用 RSS)。再者,QQ 和 MSN 对于自家的空间有良好的支持,如果有文章更新的话会有小星星或者小黄花的提示。这样我们如果将文章同步到 Qzone 及 Live Space 上,则可以达到一个推广的效果,可以利用之。

李光明同学写了一个 Post2qzone 插件,用来将 WordPress 中发布的文章同步到 Qzone 中。插件的原理比较容量理解。Qzone 和 Live Space 都支持邮件发布的功能。也就是说,可以通过发邮件到指定的邮箱来更新你的 Qzone 和 Live Space。但由于 Qzone 的邮件发布只接受从 QQ Mail 寄来的邮件,这就要求必须使用 QQ 邮箱的 SMTP 服务向 Qzone 的指定邮箱发信以同步更新 Qzone。 Live Space 的要求则宽松一些,可以自行设置发信的邮箱地址。

安装和设置

在安装前,首要先确认你的空间支持 socket 功能。没有此功能将无法使用 SMTP 服务来发送邮件,也就无法实现发布文章时同步更新。在 PHP 中调用 phpinfo() 函数,输出信息中有一个“Sockets support”,支持的话显示为 Enabled。

接下来是开通 QQ 空间、QQ 邮箱。登录到 QQ 邮箱,进入“设置”->“账户”,勾选“开启POP3/SMTP服务”,然后保存更改。这样就打开了 QQ 邮箱的 SMTP 功能。

然后下载 post2qzone.php,上传到 WordPress 插件目录,然后从插件面板启用此插件。在“设置”中有一个“Post2qzone”的页面。在此页面中设置你的 QQ 号、邮箱密码、邮件标题和邮件正文模板。

设置完成以后邮件同步发布应该就可以实现了。记得在 WordPress 中发布文章的时候,要在页面的“Post to qzone”选项中中勾选“Confirm publish”才会同步。临时不需要同步功能,可以去掉这个选项。

优化与提高

说了半天都是在说 Qzone 的事情,如何同时同步到 Live Space 呢?首先要在 Live Space 中启动邮件发布功能。登录到 Live Space,选择“选项”->“邮件发布”,在第一步中填入qq邮箱的地址;第二步中自己编造一个 secret word ,第四步中选择“立即发布”。然后直接用文本编辑器打开 post2qzone.php 插件文件,在 function Halo() 下面添加一行代码,就可以同时更新到 Live Space 上。

	function Halo($subject,$body){
		// BLOGNAME 替换为你的 Live Space 名称。比如网址 blogtest.spaces.live.com ,那么 BLOGNAME 就是 blogtest
		// SECRET 替换为 Live Space 设置中自己设定的单词,不要公开
		$this->AddAddress("BLOGNAME.SECRET@spaces.live.com","BLOGNAME.SECRET@spaces.live.com");
		$this->AddAddress("{$this->qq}@qzone.qq.com", "{$this->qq}@qzone.qq.com");
		$this->Subject = $subject;
		$this->Body	= $body;
		return $this->Send();
	}

添加好此代码以后,就可以同时通过邮件来更新 Qzone 和 LiveSpace 了。

由于此插件默认输出的是全文,为了增加自己博客的访问量,可以在插件中只输出摘要,同时给出原文链接。示意图如图所示。(此文为博客迁移后导入,图片已薨) 

怎么改我就不详细说了,无非是借用了 Advanced Excerpt 插件的处理思路来输出指定长度的摘要。我的 post2qzone 插件文章内容模板是这么写的,如下列出作为参考,摘要的效果可以在我的Live Space 上看到。

〖原文发表于<a href=”http://blog.xiaoding.org” target=”_blank”>我的部落格</a> http://blog.xiaoding.org 〗<br /><br />
{post_content}<br /><a href=”{post_link}”>阅读原文»</a> 

这儿是修改好的 post2qzone 插件的下载。(附件已遗失,不提供下载,可依文章思路自行修改)使用到了 mb_substr() 函数,不支持此函数的同学请自行依靠 Google 解决……