OK, so I read some more posts about how to analyze speed, turns out that the free pagespeed.web.dev is just awesome, it will tell you what’s going on with mobile and desktop. The gtmatrix is also good but unless you pay you are getting a 28-day average which is less useful (except to show how slow the site is).
There appear to be a few issues that have now seemly gone away. Once I installed Super Cache speed improved dramatically, but then looking at what was going on I found some unobvious stuff:
- Image caching. For whatever reason Cloudinary was not caching things and some WordPress native files are too large. They don’t have the appropriate size.
- The biggest thing though is the Instagram widget. I had it set for 9 images in 3×3 format, that alone was taking 1.5 seconds and the images were too big. When I shrunk this to 3 of my latest images, this reduced the load times and somehow the images were the right size. A good lesson that you need tools like this., I would never have suspected a widget was causing all the problems! The main issue is that the Instagram widget sends huge files that are 1080p for a tiny little thumbnail. The thing I did was to just have a single image instead of 9 and this helped alot.
- There was a message about no object caching, so I looked up how to install Redis which caches MySQL queries for speed in large sites. I don’t think I need this, but good to learn how to install it redis-server and also the Redis plugin. The other option is to install a PHP-only plugin that caches the SQL queries as PHP files and see if that helps.
- Anyway, the net is that WordPress is still complaining about not having a module called ‘intl’ in site health and I’m going to figure out how to install that just to get rid of the performance message.
It’s interesting that all the Mastodon and Activity-related stuff I also will remove. I suspect that these are causing more traffic, but we will need to see if that makes a difference, right now in looking at the logs, it looks like it is the images that are the big problem.
The Seven levels of hell that is WordPress caching
Wow, I never thought it would be this complicated, but to get a WordPress site really working requires that you make sure that no less than seven levels of caching are installed and running. This is because WordPress isn’t designed for speed. Fundamentally, it uses an interpreted language PHP, stores all the content in a MySQL database, and then assembles these pieces including images from files. It does all this completely dynamically every time there is a web request. So it needs these levels of caching:
- PHP Operation Caching. Since PHP itself is an interpreted language. at the lowest level, it takes the PHP code that is running over and over and converts it to low-level operations codes. Of course, there are a large number of different caching schemes, but if you are using PHP 7 or higher, Opcache is integrated into it, so you should get it automatically. You can check performance by loading the OpCache Manager plugin. This comes in the PerfOps One console and shows you all the cache hits that you are getting with this. Comforting to know that you are getting this 3x speedup đ
- MySQL Object Caching. Since you are running lots and lots of MySQL queries as many as 50-100 per page, you can cache the results. The goto system here is Redis but this means you have to have it installed in your environment
apt install redis-server
is your friend and then make sure that PHP can see it by editing php.ini. You can use the Redis Cache plug-in to make sure it is happening. If you don’t want to go to this trouble, there is a plugin that does this in plain PHP if you can’t access your underlying server called Docket Cache. You can also use Memcached but for some reason most prefer Redis because long term it scales better across clusters, so might as well learn how to use it. Redis does require a command line installation with apt install redis-server and then you need to make sure the/etc/redis/redis.conf
server works with systemd on Ubuntu with asupervised systemd
line and you should see it working with asystemctl start redis.service
. Then you can add the Redis Object Cache and the Redis Object Plugin and you just choose enable and it works. Note there are some security things that you should do such as restricting redis to run only on localhost applications and adding a password. So make sure in the redis.conf thatbind 127.0.0.1 ::1
is turned on which is the default. And also you can set a password for redis access inrequirepass
directive. And make sure it is a super strong password likeopenssl rand 60 | openssl base64 -A
. Then you take that password and you have to enter it into wp-config.php asdefine('WP_REDIS_PASSWORD','the password';
Note that you there are valid characters so you can’t just use a random assortment but the base64 encoding does work. - Image Sizing and Caching. OK, so the next problem is that you need different images all the time
- Page Caching. This means that the elements of the pages themselves are cached. WP Super Cache is a separate add-on needed for this. It is a big deal for my site it speeded up page creation by 1.5 seconds
- CDN Caching. You want all those pages not to be just on your server but spread out in the Content Distribution Network as well. Cloudinary does this for their images and you can also have JetPack Boost do this for local images.
- CSS and Javascript Minification. You collect all the many style sheets and javascript and compress them so they are as small as possible. YOu can also point them to fast places (not your slow little server)
- Browser Caching. Finally, the local browser will cache as much as it can of all of the above.
Confused yet?
Other Performance Issues: PHP Modules intl
The final thing that is small is that there are two modules imagick and intl that should be installed. YOu need the PHPinfo plugin to see what php modules are loaded. And my Digital Ocean system neither of these are loaded. So you need to go to a terminal figure out what version of PHP you are running from the plugin and then you need to do a apt install php7.4-intl
and then you make sure the php.ini file recognizes it. It’s not easy to find, but for Apache2 its in /etc/php/7.4/apache2/php.ini
and you want to uncomment the extension=intl
line and do a service apache2 restart
Pretty tricky and I’m not sure it makes a difference.
Mobile is much slower than Desktop
One of the things I learned is that the mobile performance is much worse than desktop. One reason is that the PageSpeed business a 3G connection, so you are talking about a slow device on a slow connection. And for our site, the big problem is that the images are just too big on the device.
Regenerating Critical CSS and other JetPack Boost settings
JetPack Boost is the core thing I use and it has a bunch of optimizations, the one manual one is called “Critical CSS Loading” which basically reorders the styles so you can display faster. The free version has you adding a manual recreate everytime you edit the file. There are others like defere non-essential Javascript and concatenation of JS and CSS and also and Image CDN that are on. This seems like overlap with Cloudinary, so I’m not sure if I should turn it on.