Everyone wants to make the most of the least and for this we must head for smart choices. After many searches and test-driving solutions and complex combinations of memcached, redis, tmpfs ramdisk and various WordPress plugins I found a decent combination that everyone can apply.
For prerequisites I will point to other posts of mine and will concentrate on optimizations for this one.
Goals to achieve:
- High Availability
- Load balancing
- Scalability
- Centralized storage
- Reduced server overhead and fast loading content
Prerequisites:
- HAProxy load-balancer cluster
- Galera cluster for database – http://www.zeding.ro/galera-cluster-for-mysql-true-multi-master-on-centosrhel-7-x/
- GlusterFS for storage – http://www.zeding.ro/glusterfs-replicated-distributed-storage-pool-on-centosrhel-7-x/
First if you have a classic WordPress installation test it’s performance here: http://gtmetrix.com and they will give you a detailed report and also suggestions what you should improve.
I was running a poor performing WP until now and decided to take action.
Steps:
Setup a galera cluster and migrate your database into
Then point wp-config.php
to use the floating IP of Galera Cluster.
Setup you new WP instances
for host in {wordpress01,wordpress02}; do ssh $host \
"yum -y install httpd"; done
for host in {wordpress01,wordpress02}; do ssh $host \
"rm -fv /etc/httpd/conf.d/welcome.conf"; done
for host in {wordpress01,wordpress02}; do ssh $host \
"tee /etc/httpd/conf.d/wordpress.conf << wp_alfa_beta
<Directory "/wordpress">
AllowOverride All
</Directory>
<filesMatch "\.(jpg|jpeg|js|html|css)$">
SetOutputFilter DEFLATE
</filesMatch>
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName domain.tld
ServerAlias http://www.domain.tld
DocumentRoot /wordpress
</VirtualHost>
wp_alfa_beta"; done
Make sure you have a running GlusterFS on decent hardware
On every WP instance do:
mkdir /wordpress
yum -y install nfs-utils attr
systemctl enable rpcbind && systemctl start rpcbind
mount -t nfs gluster01.stor.domain.tld:/wordpress /wordpress
With a small comment here: if you are running WP instances and GlusterFS nodes as virtual machines on common hypervisors point every WP instance to the closest GlusterFS node.
Do not use glusterfs-fuse because it is slow and does not cope.
Example:
hv01: wordpress01, gluster01
hv02: wordpress02, gluster02
[[email protected] ~] mount -t nfs gluster01.stor.domain.tld:/wordpress /wordpress
echo "gluster01.stor.domain.tld:/wordpress /wordpress nfs defaults,_netdev 0 0" >> /etc/fstab
[[email protected] ~] mount -t nfs gluster02.stor.domain.tld:/wordpress /wordpress
echo "gluster02.stor.domain.tld:/wordpress /wordpress nfs defaults,_netdev 0 0" >> /etc/fstab
Sync your old content to the GlusterFS storage
[[email protected]_old ~]# rsync -avzr /var/www/html/* [email protected]:/wordpress/
[[email protected] ~]# chown -R apache.apache /wordpress/*
Start you WP instances and get ready
for host in {wordpress01,wordpress02}; do ssh $host \
"systemctl enable httpd && systemctl start httpd"; done
High Availability and Load Balancing will be achieved via HAProxy
We presume HAProxy is already installed.
vi /etc/haproxy/haproxy.cfg
and add something similar:
# Frontends
listen http *:80
option http-server-close # very important for keep-alive
option forwardfor except 127.0.0.0/8
acl wordpress hdr(host) -i domain.tld
use_backend wp_cluster if wordpress
# Backends
backend wp_cluster
server wordpress01 192.168.100.101:80 check
server wordpress02 192.168.100.102:80 check
Cache validator inside .htaccess
Make sure you .htaccess contains ETag header
<FilesMatch "\.(html|htm)$">
AddDefaultCharset UTF-8
<ifModule mod_headers.c>
Header unset Pragma
FileETag INode MTime Size
Header set Cache-Control "public, max-age=604800, must-revalidate"
Header set Connection keep-alive
</ifModule>
</FilesMatch>
<FilesMatch "\.(?i:ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|x-html|css|xml|js|woff|woff2|ttf|svg|eot)(\.gz)?$">
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A0
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/ico A2592000
ExpiresByType image/svg+xml A2592000
ExpiresByType text/css A2592000
ExpiresByType text/javascript A2592000
ExpiresByType application/javascript A2592000
ExpiresByType application/x-javascript A2592000
</IfModule>
<IfModule mod_headers.c>
Header unset Pragma
FileETag INode MTime Size
Header set Cache-Control "public, max-age=2592000"
Header set Connection keep-alive
</IfModule>
</FilesMatch>
Once you have you WP running it’s time to optimize content
The best plugins I could find until now are:
Most efficient .css & .js minify solution until now
wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/yuicompressor-2.4.8.jar
yum install java-1.8.0-openjdk
cd /wordpress/wp-content/themes/<theme>
for i in `ls . |grep .css`; do cp -p "$i" "$i"_orig && java -jar /root/yuicompressor-2.4.8.jar --type css -o "$i" "$i"_orig; done
cd /wordpress/wp-content/themes/<theme>/css
for i in `ls . |grep .css`; do cp -p "$i" "$i"_orig && java -jar /root/yuicompressor-2.4.8.jar --type css -o "$i" "$i"_orig; done
cd /wordpress/wp-content/themes/<theme>/js
for i in `ls . |grep .js`; do cp -p "$i" "$i"_orig && java -jar /root/yuicompressor-2.4.8.jar --type js -o "$i" "$i"_orig; done
WP Fastest Cache (generates persistent static html content for every dynamic page) – download
Features:
- Mod_Rewrite which is the fastest method is used in this plugin
- All cache files are deleted when a post or page is published
- Admin can delete all cached files from the options page
- Admin can delete minified css and js files from the options page
- Block cache for specific page or post with Short Code
- Cache Timeout – All cached files are deleted at the determinated time
- Cache Timeout for specific pages
- Enable/Disable cache option for mobile devices
- Enable/Disable cache option for logged-in users
- SSL support
- CDN support
- Preload Cache – Create the cache of all the site automatically
Performance Optimization:
- Generating static html files from your dynamic WordPress blog
- Minify Html – You can decrease the size of page
- Minify Css – You can decrease the size of css files
- Enable Gzip Compression – Reduce the size of files sent from your server to increase the speed to which they are transferred to the browser.
- Leverage browser caching – Reduce page load times for repeat visitors
- Combine CSS – Reduce number of HTTP round-trips by combining multiple CSS resources into one
- Combine JS
WP Smush – Image Optimization (does Lossless image optimization) – download
Features:
- Optimize your images using advanced lossless compression techniques.
- Process JPEG, GIF and PNG image files.
- Auto-smush your attachments on upload.
- Manually smush your attachments individually in the media library, or in bulk 50 attachments at a time.
- Smush all standard web-sized images 1MB or smaller.
- Smush images with no slowdown using WPMU DEV’s fast, reliable Smush API.
- View advanced compression stats per-attachment and library totals.
WP Deffered JavaScripts (delays the load of JavaScripts for faster response)
This plugin defer the loading of all JavaScripts added by the way ofwp_enqueue_script()
, using LABJS. The result is a significant optimization of loading time.
It is compatible with all WordPress JavaScript functions (wp_localize_script()
, js in header, in footer…) and works with all well coded plugins.
ShortPixel Image Optimizer
ShortPixel makes your website load faster by reducing the size of your images and helps you rank better in Google search. With both lossy and lossless image compression available for all common image types (PNG, JPG, GIF), plus PDF files. The plugin is free to use for 100 images/month.
How does it work?
Both new and old images can be optimized with ShortPixel. Once activated, the plugin instantly processes new images uploaded to your website. Bulk optimization will automatically process all your past image gallery with one click. Images and thumbnails are processed in the cloud, and replaced back into your website. It’s simple to use, yet incredibly powerful.
Plugin features. What you see is what you get:
- supports PNG, JPG, GIF (still and animated) images and PDF documents
- thumbnails and featured images are also optimized
- CMYK to RGB conversion
- free 100 image credits/month. Images that are optimized less that 5% are bonus
- no file size limit
- originals are saved in a backup folder and can be manually restored
- ‘Bulk’ optimize past gallery with one click
- 40 days optimization report with all image details and overall statistics
- works great for eCommerce websites using WooCommerce plugin
- multisite support for a single API key
- compatible with WP Engine hosted websites
- compatible with WPML and WPML Media plugins.
Test the performance of you WP again
Performance test here: http://gtmetrix.com and compare the detailed report for more suggestions what you could improve.