WordPress/woocommerce性能优化

默认安装的 WordPress 性能表现很一般,尤其如果添加了 woocommerce 插件后,后台总有一种卡顿的感觉,为了提升 WordPress/woocommerce 的使用体验,需要进行一些性能优化操作。WordPress 本身是一个基于 PHP 实现的程序,因此要优化使用体验就要在 LNMP/LAMP 架构的组件配置上进行调整。这篇文章介绍一些 LNMP 架构中,对于 WordPress 性能有影响的配置项,理论上应该也适用于其他 PHP 项目。

注意:本篇文章需要技术背景,标记★代表强烈建议启用

一、Nginx配置

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 60;

1.1 GZIP压缩

gzip on;
gzip_vary on;
gzip_disable "msie6";
gzip_min_length 1k;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/x-httpd-php;

1.2 静态缓存★

location ~.*.(js|css|html|png|jpg|jpeg|gif|gz|svg|mp4|ogg|ogv|webm|htc|xml|woff|zip|webp)$
{
    access_log off;
    expires  30d;
    try_files $uri =404;
}

二、PHP配置

2.1 opcache配置★

[opcache]
; 启用opcache
opcache.enable = 1

; opcache使用的内存量
opcache.memory_consumption = 256M

; 存储字符串的缓冲区大小,单位是MB
opcache.interned_strings_buffer = 32

; 可存储的脚本文件数量上限
opcache.max_accelerated_files = 1979

; 设置重新验证脚本缓存的频率,以秒为单位。如果设置为0,则每次请求都会重新验证缓存
opcache.revalidate_freq = 60

; 启用或禁用时间戳验证。如果启用此功能,OPcache会在每次请求时检查脚本的时间戳以确定是否需要重新加载脚本
opcache.validate_timestamps = 0

; 启用会将缓存持久化到文件
opcache.file_cache = 0

; 是否将注释保存到缓存中,如果依赖注释中的注解需要启用,wordpress中没有使用
opcache.save_comments = 0

; php8以上版本启用jit
opcache.jit = 1235
opcache.enable_cli = 1

2.2 预加载

预加载从PHP7.4开始支持,具体可以参考4.2

三、WordPress调整

可以通过直接修改WordPress配置文件(wp-config.php)或者安装插件进行的优化项目。

3.1 关闭默认的CRON执行器

define( 'DISABLE_WP_CRON', true );

可以通过系统的crontab来执行定时任务:

# 修改crontab配置
crontab -e

# 添加下面行
* * * * * php -f /path/to/wp-cron.php

3.2 静态文件压缩

define( 'COMPRESS_CSS', true ); // 压缩CSS
define( 'COMPRESS_SCRIPTS', true ); // 压缩JS
define( 'ENFORCE_GZIP', true ); // 强制启用GZIP,如果WEB服务器启用了GZIP可以不开启
define( 'CONCATENATE_SCRIPTS', true ); // 连接脚本

3.3 插件优化

插件也会对WordPress的性能有很大影响,有一些优秀的插件会极大优化WordPress性能表现,可以参考下面文章。

四、MySQL/MariaDB数据库配置优化

4.1 数据库配置优化

适用于小型实例,中大型示例参考参数备注进行调整。数据库my.cnf配置文件中添加以下配置:

# 表定义缓存数量,最低400
table_definition_cache = 400
# 打开表缓存
table_open_cache = 500
# 关闭performance_schema,大型实例不建议采用,大概能节省数据库默认占用一半的内存
performance_schema = off

# innodb的缓存
# 数值越大,内存中占用越大,同时数据库性能也会提高。纯数据库服务器可以使用内存的 70%-80% 。
# 单机部署时最好多测试一下
innodb_buffer_pool_size = 256M

# 尽可能增加innodb_buffer_pool_size
innodb_buffer_pool_size = 512M

# 决定了事务日志何时被写入并刷新到磁盘上
# 0:每秒将日志写入并刷新到磁盘
# 1:每次事务提交时,都将日志写入并刷新到磁盘
# 2:每次事务提交时,都将日志写入日志缓冲区,但仅在每秒刷新到磁盘
# 选择0/2,宕机时有可能丢失1秒内事务数据
innodb_flush_log_at_trx_commit = 0

4.2 持久化数据库连接

查看WordPress性能团队的聊天记录突然发现WordPress默认情况下是没有启用持久连接的(数据库连接池),会导致每一次的请求都需要初始化数据库连接。解决办法比较简单,在 wp-content 目录下放一个 db.php 文件,写入以下内容,然后在配置文件中添加一个值为 trueDB_PERSIST 常量即可。

这个小问题应该会在不久的未来经过测试后合并到WordPress核心中,此方法只适用于未合并前的这段时间,合并后就不需要了,目前6.5.2版本暂时还没有提供。

关于PHP中的持久化连接,有兴趣可以参考官网中以下两篇文章:

4.3 PHP预加载

这部分是确定不会带来什么问题的,其他的应该还有很多也可以预加载,但是没有测试过,后面更新再说。

; 这是php.ini配置文件,确保PHP版本>=7.4
; Specifies a PHP script that is going to be compiled and executed at server
; start-up.
; https://php.net/opcache.preload
;opcache.preload=
opcache.preload=/var/www/html/preload.php
<?php

/**
 * 使用OPcache优化WordPress的预加载脚本。
 * 
 * 参考文档: https://www.php.net/manual/zh/opcache.preloading.php
 */
// Define the base path for WordPress
define('WP_ROOT_DIR', __DIR__ . '/wordpress');

// wp-includes
require WP_ROOT_DIR . '/wp-includes/class-wp.php';
require WP_ROOT_DIR . '/wp-includes/class-wpdb.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-query.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-widget.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-roles.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-user.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-user-query.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-post.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-error.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-term.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-term-query.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-theme.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-theme-json.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-tax-query.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-site.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-dependencies.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-scripts.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-object-cache.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-network.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-admin-bar.php';
require WP_ROOT_DIR . '/wp-includes/class-wp-application-passwords.php';

// wp-admin/includes
require WP_ROOT_DIR . '/wp-admin/includes/class-wp-list-table.php';
require WP_ROOT_DIR . '/wp-admin/includes/class-wp-media-list-table.php';
require WP_ROOT_DIR . '/wp-admin/includes/class-wp-plugins-list-table.php';
require WP_ROOT_DIR . '/wp-admin/includes/class-wp-posts-list-table.php';
require WP_ROOT_DIR . '/wp-admin/includes/class-wp-screen.php';

以上就是LNMP架构中各组件的一些优化配置,文章持续更新中。