WordPress 安装很方便,可以说是开箱即用。但是随着文章增多,访问量增大,会发现 WordPress 很“慢”。这是 WordPress 本身的 PHP 运行机制导致的,每篇文章都要去数据库读取,而且 WordPress 为了支持各种功能,现在已经非常臃肿,每次请求都要加载很多东西。但正是 WordPress 的功能强大,让我们也能很方便的做各种优化。
目录
0x1 使用最新版本的 PHP 和 MySQL
毫无疑问升级基础运行环境是提高性能最好的方式之一。特别的 PHP7 和 MySQL 5.7 较之前的版本性能提升很大。还可以根据服务器配置适当调整 PHP-FPM 和 MySQL 参数。
0x2 使用缓存
这里的缓存有两层意思,一是 PHP 层面的运行数据缓存,二是文章页面静态化。这里推荐几个插件来解决这个问题:
Redis Object Cache
一款持久对象缓存插件。其实 WordPress 本身带有对象缓存功能,但是是把序列化的对象缓存在文件中,效果不是很好。这个插件通过重写 object-cache.php 文件,把对象缓存到 Redis。直观的感受就是不光前台页面加载速度快了,而且后台响应速度提升更大。
Cache Enabler
keycdn 公司开发的一款页面静态化缓存的插件。相比 wp-supercache 等插件更加简洁和强大。建议按照官方说明进行增强设置,官方的配置有一点小问题,当你的永久链接格式设置为 xxx.html 时 $cache_uri(默认是 $request_uri)没有后面的 / 拼凑的文件路径不对(xxx.htmlindex.html),需要改成 ${cache_uri}/index.html,这样虽然访问首页时中间会多个 / 但也不影响。
1 2 3 4 5 6 | # default html file set $cache_enabler_uri '${custom_subdir}/wp-content/cache/cache-enabler/${http_host}${cache_uri}/index.html'; # webp html file(按需开启) if ($http_accept ~* "image/webp") { set $cache_enabler_uri '${custom_subdir}/wp-content/cache/cache-enabler/${http_host}${cache_uri}/index-webp.html'; } |
我使用的是 Nginx,除了正常设置 gzip 外还开启了 gzip_static 参数,让 Nginx 在读取文件的时候优先读取带 gz 后缀的静态文件,不用再做 gzip 压缩。
顺带推荐一个 gzip 检查网站:https://www.giftofspeed.com/gzip-test/
不过使用高级设置后需要把缓存有效期设置为 0(永不失效),可能会造成缓存不会被更新(正常情况下更新文章缓存会被更新)。这里我是通过删除缓存文件然后访问自己 sitemap 中的链接来刷新缓存:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #!/usr/bin/env python3 # -*- coding: utf-8 -*- # rebuild cache according to sitemap.xml import os import requests import xml.etree.ElementTree as ET import time import shutil CACHE_DIR = "/var/www/wordpress/wp-content/cache/cache-enabler/" SITEMAP_URL = "https://iyaozhen.com/sitemap.xml" if os.path.isdir(CACHE_DIR): shutil.rmtree(CACHE_DIR) try: sitemap = requests.get(SITEMAP_URL) except (requests.HTTPError, requests.ConnectionError) as e: print("get sitemap.xml error: %s" % e) else: urlset = ET.fromstring(sitemap.content) print("start rebuild cache at %s" % time.asctime()) for url in urlset: loc = url[0].text try: requests.get(loc) except (requests.HTTPError, requests.ConnectionError) as e: print("request %s error: %s" % (loc, e)) else: print("hit %s" % loc) finally: time.sleep(0.1) else: print("no cache dir: %s" % CACHE_DIR) |
https://gist.github.com/iyaozhen/53e6a57a2f7e945ba1161953959a7cb2
Nginx open_file_cache
上一步我们已经将网站静态化,访问一般的文章页面,其实相当于打开 html 文件,但文件打开关闭也是有开销的,这个能否优化呢?答案是可以的,nginx 提供了 open_file_cache 功能,简单配置即可
1 | open_file_cache max=100 inactive=3600s; |
此配置是让 nginx work 保持最常访问的文件句柄,不是缓存文件内容(nginx 发送文件是内核态直接发送的,不用应用层用户态保持文件内容),对于中小站点很实用,我们可以通过 sudo lsof -p pid
查看进程打开的文件句柄。这一通骚操作后,TTFB 能降到 10ms 以下。
0x3 使用 CDN 和图片压缩
用户有时候感觉网站慢,更多的是静态资源加载慢。页面上的 JS、CSS、图片等都需要消耗服务器带宽。而且中国地域辽阔,跨地区、跨运营商更是问题。这时就需要 CDN 了。现在国内各个云都在相互竞争,CDN 比较便宜,免费的也有很多。我之前使用的是七牛云,不过自从服务器迁到腾讯云之后, CDN 也换到了腾讯(免费12个月)。这里推荐同为 keycdn 出的 CDN Enabler 插件,能将页面中的链接替换为 CDN 链接。同时推荐使用 WP Smush、Compress JPEG & PNG images 压缩图片(有条件的还可以付费开启 webp),还有使用 BJ Lazy Load 实现图片懒加载(显著提高首屏加载速度)。最后不要忘记站点和 CDN 都配置一下防盗链。
0x4 升级到 HTTP2
HTTP2 支持请求复用,能提高50-70%的加载速度。首先要配置 HTTPS,再简单的配置下就能支持 HTTP2 了。当然静态资源使用的 CDN 最好也要支持 HTTP2,目前国内厂商基本都支持。
0x5 配置dns-prefetch
、preconnect
和prerender
等资源加载参数
dns-prefetch
即 DNS 预加载,表示在页面加载前就先进行 DNS 解析,示例:<link rel="dns-prefetch" href="//example.com">。
preconnect
资源预连接,预先建立与一个域名的连接,包括 DNS 查询、TCP 握手、TLS 协商,有点类似于后端经常使用的连接池概念,后续同一域名的请求高优先使用已建立的连接,提高连接效率(但不保证不会再新建连接,这和具体浏览器策略有关)。设置示例:<link rel="preconnect" href="//example.com"> 或 <link rel="preconnect" href="//cdn.example.com" crossorigin>。具体细节可参考这篇文章:https://www.igvita.com/2015/08/17/eliminating-roundtrips-with-preconnect/。不过这人觉感觉如果已经支持 HTTP2 了的话,就不用使用这个参数了。
prerender
预先请求,经常用在热门文章或者下一页场景。比如预先请求好下一页的内容,当用户点击下一页时嗖的一下就跳到下一页去了,极大地提高了用户体验。
这三个参数都可以通过插件 Instant Articles 设置,不过提醒一下预加载也不是设置的越多越好,毕竟浏览器能发起的 HTTP 请求是有限的,可能会适得其反。
0x6 优化效果评测
做了这么多优化怎么量化前后的效果呢,推荐使用 https://gtmetrix.com/ 测试一下(跑个分),这个网站提供真实浏览器的打开情况报表(不过他们服务器在国外,加载时间会长点),并提供很多速度优化和 SEO 建议(很实用)。国内测速可以使用:https://www.17ce.com/。
0x7 其它实用插件推荐
wpDiscuz 自带PL增强插件,在样式和功能上都提升较大。特别是最近多说关闭,让我更觉得还是自建的系统靠谱。
Contextual Related Posts 相关文章推荐插件,减小用户跳出率,提高用户粘性。
Ultimate Tag Cloud Widget 标签云插件。
Wordfence Security、iThemes Security 安全设置、防火墙。
WP-PostViews 文章阅读数插件。
多合一SEO包 SEO 插件,基本上用这个插件做下 SEO 也就够了。
Easy Table of Contents 自动生成文章目录。
Health Check & Troubleshooting WordPress 官方出品的健康检查插件,可以查看系统各种设置是否正确。
Quotmarks Replacer WordPress 对双引号处理的不太好,这个插件可以解决问题。
WP Config File Editor 配置文件编辑插件,可以方便设置一些值。
失效链接检查器 顾名思义,就是检查文章中的哪些链接失效了。
Crayon Syntax Highlighter 代码高亮插件,程序员必备。
参考资料
WordPress Performance – Breaking It Down by HTTP Requests,https://www.keycdn.com/blog/wordpress-performance
18 Tips on How to Speed Up WordPress,https://www.keycdn.com/blog/speed-up-wordpress
W3C-Resource Hints,https://html.spec.whatwg.org/#linkTypes
Resource Hints – What is Preload, Prefetch, and Preconnect?,https://www.keycdn.com/blog/resource-hints
Nginx tuning tips: TLS/SSL HTTPS – Improved TTFB/latency,https://linuxblog.io/nginx-tuning-tips-tls-ssl-https-ttfb-latency/
Nginx性能提升 - open_file_cache指令,https://juejin.cn/post/6844903779578413064