上一篇文章讲了动静分离、CDN 和图片压缩,这些都属于”外部”提速手段:把流量从主站转移出去,或者让文件更小。但网站真正跑起来的地基,还是服务器本身。一台配置不合理、软件层没优化的服务器,无论前端怎么做,动态请求的处理速度都上不去。这篇文章从 Nginx 与 Apache 的选择讲起,依次拆解 OPCache、MySQL Query Cache、Gzip 压缩和 expires 头信息四个服务器层面的优化项,每一段都给出可以直接复制的配置代码,照着做就能让 WordPress 的响应速度上一个台阶。
使用 Nginx 替代 Apache
Web 服务器是 WordPress 处理请求的第一站,最常见的两个选择是 Apache 和 Nginx。Apache 对 PHP 的兼容性更好,很多老主机商默认就装它,虚拟主机上用起来几乎不用配置。但 Apache 的问题在于重:每个连接都要占用不少系统资源,在高并发场景下内存和 CPU 消耗非常可观。Nginx 则采用事件驱动的架构,本身非常轻量,同样的硬件条件下能支撑更多的并发连接,占用的系统资源却少得多。
对 WordPress 来说,Nginx 节省下来的资源并不是白白省下的,它们可以被 PHP 使用。PHP 是 WordPress 的核心执行引擎,资源越充裕,动态页面的处理就越快。所以现在的云主机和 VPS 环境里,Nginx + PHP-FPM 几乎成了标准组合。如果你的站点还跑在 Apache 上,并且经常感觉服务器资源吃紧,换到 Nginx 通常是性价比最高的一步。当然,如果网站流量很小、Apache 也跑得很稳,暂时不动也没问题,优化不必一步到位。
为 PHP 开启 OPCache
什么是 OPCache
PHP 是解释型语言,每次请求进来,解释器都要把脚本源码从头分析一遍,生成可以直接运行的中间代码,也就是操作码(OPCode)。同一份代码被访问一百次,就要重复编译一百次,CPU 和内存都花在了重复劳动上。OPCache 的作用就是把编译好的操作码缓存起来,下次请求直接复用,避免重复编译,大幅减少 CPU 和内存开销。

不过 OPCache 不是万能的,它的提升效果取决于你的瓶颈在哪。如果网站慢是因为 CPU 和内存吃紧,OPCache 的收益会非常明显;但如果瓶颈在 I/O 操作,比如数据库查询带来的磁盘读写开销,那么 OPCache 对性能的提升就非常有限,这时候该去优化数据库,而不是盯着 PHP 的编译缓存。先搞清楚瓶颈在哪,再决定要不要开、开了期望什么效果。
启用 OPCache
默认情况下 PHP 会安装 OPCache,但并不会启用。在 php.ini 里添加下面这段配置,然后重启 PHP 服务即可生效。这里整理了一份完整的推荐配置,逐行都有注释说明作用:
; 开关打开
opcache.enable=1
; 可用内存酌情而定,单位 megabytes
opcache.memory_consumption=256
; 对多缓存文件限制,命中率不到 100% 的话,可以试着提高这个值
opcache.max_accelerated_files=7963
; Opcache 会在一定时间内去检查文件的修改时间,这里设置检查的时间周期,单位为秒
opcache.revalidate_freq=240
; 是否快速关闭,打开后在 PHP Request Shutdown 的时候回收内存的速度会提高
opcache.fast_shutdown=1
; 不保存文件/函数的注释
opcache.save_comments=0
配置里几个参数值得单独说一句。memory_consumption 是缓存占用的内存上限,一般 256M 对中小站点足够,文件多的站可以调到 512M。max_accelerated_files 控制最多缓存多少个 PHP 文件,如果开启后命中率不到 100%,可以适当调高这个值,但要留意服务器内存是否够用。revalidate_freq 是检查文件修改时间的周期,默认 2 秒,改成 240 秒可以减少不必要的文件检查,但改源码后需要等几分钟才生效,开发环境建议保持小值。
为 MySQL 开启 Query Cache
数据库查询是 WordPress 动态页面的主要耗时来源之一。MySQL 的 Query Cache 会把查询语句和对应的结果缓存起来,同样的查询再次执行时直接返回缓存结果,不再走磁盘。在 MySQL 配置文件 my.cnf 中添加下面三行,重启 MySQL 即可开启:
query_cache_type = 1
query_cache_limit = 1M
query_cache_size = 16M
query_cache_type 设为 1 表示开启缓存,query_cache_limit 限制单条查询结果最多缓存多大,query_cache_size 是缓存区总大小,16M 是常见的起步值。但这里必须提醒一句:Query Cache 并不适合所有场景。如果你的博客浏览量较大、内容更新频率不高,开启后命中率会很高,收益明显;如果内容更新频繁而浏览量不大,每次更新都要失效对应的缓存,维护缓存本身反而成了额外开销,Query Cache 反而可能带来负效应。所以开之前先想清楚自己的站属于哪种类型,别盲目照抄配置。
为服务器开启 Gzip 压缩
Gzip 压缩可以在传输前把 HTML、CSS、JavaScript 等文本类文件压缩,通常能减少 60% 到 80% 的传输体积,页面加载速度的提升立竿见影。开启 Gzip 的方式有好几种,覆盖了从虚拟主机到独立服务器的全部场景,你可以按自己的环境选一种。
在 WordPress 中开启
最简单的做法是在根目录的 index.php 中添加一行代码,放在 define(‘WP_USE_THEMES’, true); 之后,让 PHP 在输出前对内容做 Gzip 压缩:
ob_start('ob_gzhandler');

这种方法对虚拟主机最友好,不需要改任何服务器配置。不过更推荐的做法是优先用服务器层面的压缩,把 PHP 的时间留给页面本身。
通过 Apache 的 .htaccess 文件开启
如果你用的是 Apache,可以在网站根目录的 .htaccess 文件中添加下面的代码,同时开启 Gzip 压缩和浏览器缓存过期时间:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/png A2592000
ExpiresByType image/x-icon A2592000
ExpiresByType application/x-javascript A604800
ExpiresByType text/css A604800
</IfModule>
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/css image/gif image/jpeg image/png application/x-javascript
</IfModule>
mod_deflate 负责压缩,mod_expires 负责给不同类型文件设置缓存时间。两个模块一起开,文本类文件被压缩传输,图片等静态文件被浏览器缓存,双管齐下。前提是主机开启了这两个 Apache 模块,绝大多数面板环境默认都有。
通过 Nginx 的 Conf 文件开启
Nginx 用户则要在 nginx.conf 的 http 段中添加下面的配置:
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_min_length 256;
gzip_http_version 1.1;
gzip_types text/plain text/css text/x-component text/html application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/x-icon image/svg+xml image/jpeg image/gif image/png font/opentype;
gzip_comp_level 是压缩级别,1 到 9 之间,6 是速度与压缩率的平衡点,设太高反而会占用更多 CPU。gzip_min_length 256 表示小于 256 字节的文件不压缩,因为小文件压缩后反而可能更大。gzip_types 列出了要压缩的文件类型,图片类虽然列上了,但 PNG、JPEG 本身已经是压缩格式,再压收益有限,主要受益的还是文本类文件。
通过 php.ini 开启
如果不想动 Web 服务器配置,也可以在 php.ini 中直接开启输出压缩。在 php.ini 末尾添加下面两行配置,然后重启 PHP 即可生效:
zlib.output_compression=On
zlib.output_compression_level = 5
这个方案和 ob_gzhandler 类似,都是在 PHP 层面压缩输出,优点是改动最小、对任何 Web 服务器都生效,缺点是会占用 PHP 进程的时间,适合没有服务器配置权限的虚拟主机用户。
通过 WP Super Cache 开启
如果你已经装了 WP Super Cache,那就不用单独配置了——插件里自带压缩选项,开启后生成的静态页面会直接以压缩形式保存。关于缓存插件的完整配置,站内的 WordPress 缓存类型详解把页面缓存、对象缓存、CDN 缓存的区别和配置讲得很清楚,值得对照着看。
为文件加入 expires 头信息
大部分时候,我们上传的图片、CSS、JavaScript 文件在很长一段时间内都不会改变。如果不设置缓存头,浏览器每次访问都要重新下载这些文件,白白浪费带宽和加载时间。通过 expires 头信息告诉浏览器这些文件可以缓存多久,之后访问就直接从本地缓存读取,加载速度会有明显提升。在 .htaccess 中添加下面的配置即可:
# BEGIN Expire headers
<ifModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 5 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
ExpiresByType text/html "access plus 600 seconds"
ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>
# END Expire headers
图片类文件缓存 30 天(2592000 秒),CSS 和 JavaScript 缓存 7 天(604800 秒),HTML 页面缓存 10 分钟(600 秒)。要注意的是,缓存时间设得越长,用户看到旧版 CSS 或 JS 的可能性越大,所以改过主题样式或脚本后,记得给文件名加上版本号或者清一下缓存,让浏览器强制拉取新文件。如果你不想手写这些规则,站内的 不用插件优化网站速度一文里还有不少类似的零配置提速技巧。
总结
服务器层面的优化是一条完整的链路:先用 Nginx 把 Web 服务器的资源占用降下来,再把省下的资源交给 OPCache 缓存 PHP 操作码,MySQL Query Cache 处理高频且少变的查询,Gzip 压缩所有文本类传输内容,最后用 expires 头信息让浏览器缓存静态文件。五步做完,动态请求和静态资源的处理效率都会有明显改善。每一步的适用场景不同:CPU 瓶颈优先 OPCache,查询瓶颈优先 Query Cache,带宽瓶颈优先 Gzip。对照自己的站点情况对症下药,比一股脑全开效果更好。如果还想从整体上了解还有哪些提速手段,站内的 WordPress 速度优化 7 个实用技巧可以给你一个全局视角。
常见问题解答(FAQ)
OPCache 的内存设多大合适?
中小型站点 256M 起步即可,文件多或插件多的站可以调到 512M。设置后通过 opcache_get_status() 查看命中率,如果命中率长期在 95% 以上说明够用,低于 90% 可以考虑加大内存或调高 max_accelerated_files。
Query Cache 什么时候该关掉?
内容更新频繁、浏览量不大的站点建议关闭,因为每次更新都会让相关缓存失效,维护缓存的开销反而拖慢速度。浏览量大且更新不频繁的站才适合开启。
Gzip 会压缩图片吗?
配置里可以列出图片类型,但 PNG、JPEG 本身就是压缩格式,再压收益很小且浪费 CPU。Gzip 的主要收益来自 HTML、CSS、JavaScript 这类文本文件,压缩率通常有 60% 到 80%。
改了 php.ini 或 my.cnf 需要重启吗?
需要。php.ini 改完要重启 PHP-FPM 或 Apache 的 PHP 模块,my.cnf 改完要重启 MySQL,配置才会生效。命令行下分别执行 systemctl restart php-fpm 和 systemctl restart mysql 即可。
宝塔面板里怎么开启这些优化?
宝塔的 PHP 设置页里有 OPCache 开关,直接开启即可;Gzip 在 Nginx 配置里取消注释对应段;MySQL 设置页可以调 query_cache 相关参数。面板环境基本都预装了所需模块,比命令行操作简单很多。
Nginx 和 Apache 能共存吗?
可以,常见的做法是 Nginx 做前端代理处理静态文件和并发,Apache 在后面处理 PHP,各取所长。但对大多数 WordPress 站点来说,纯 Nginx + PHP-FPM 已经足够,没必要为了共存而增加复杂度。
