An open collection of noteworthy things

Code

Superfast WordPress: How to use WordPress as a Static Site Generator

Introduction

WordPress is slow. Perhaps the most extensible and flexible current CMS, but likely one of the slowest as well.

By caching sites with Redis or W3 Total Cache/WP Super Cache, or through using HHVM (and any other means), we may make WordPress much faster and more efficient than usual – but even after all this, our sites still may run extremely slowly.

The biggest slowdown in the whole system – from when your browser submits a request to the server, to when it receives and renders the response (that we can address) is the time taken by the server to actually generate the webpage.

Most caching plugins help here by serving the same page to anonymous users, and regenerating the page whenever there’s a change. However, caching plugins aren’t perfect. Most of the time, they’ll need to check if the user is logged in, and if they aren’t, then serve them the page after doing a number more checks. This takes time.

In order to really, really speed up WordPress, it may be used as a static site generator – that is to say, posts/pages/etc are written and then some method is used to convert this website into plain HTML files; completely cutting PHP out of the whole path (generally a good thing, from a security standpoint too). The server never has to regenerate the page (turning it into a HTML page to then give to the browser), because it already is HTML, which it then simply serves.

To do this, NGINX will be used as it’s great at serving static files (and is overall just a very good webserver). It is assumed that WordPress is already installed on admin.example.com with NGINX.

When someone goes to www.example.com, they will be served the static version of the site – the “raw HTML” – which may easily be hosted on a CDN such as CloudFront so as to be extremely fast. To update the site, the normal WordPress URL of  admin.example.com will be used for changes and updates – and by then clicking a button, the “production” site at www.example.com will be updated accordingly.

Configuration

Ensure a DNS (A) record record pointing to the origin (i.e., the same as the one resolving admin.example.com at www.example.com) has been created.

Then, a new NGINX vhost and directory are created to host the site’s static files in:

cd /etc/nginx/sites-enabled/

sudo wget -O static-www.example.com https://bit.ly/FH2MPS

Or a file is added there with the content below:

The directory structure for the website’s static files is then created, and appropriate permissions are set:

cd /var/www/ && sudo mkdir static-www.example.com && sudo mkdir static-www.example.com/htdocs/ static-www.example.com/conf/ && sudo mkdir static-www.example.com/conf/nginx/

sudo chown -R www-data:www-data /var/www/static-www.example.com/htdocs/

Any extra NGINX config that is needed may now be placed in  /var/www/static-www.example.com/conf/nginx/something.conf:

sudo nano /var/www/static-www.example.com/conf/nginx/caching.conf

This will make NGINX feel a lot faster with serving static files.

(Note; it is a good idea to check in nginx.conf that there are good Gzip rules in place, so that the transfer may be compressed for certain file types.)

It is also a good idea to set up an SSL configuration:

sudo nano ssl.conf

A dhparam could also be generated and placed in /var/www/static-www.example.com/conf/nginx/ssl/dhparam.pem, uncommenting any relevant parts in the SSL configuration. The same can be said about HSTS, Stapling and other miscellaneous parameters.

Redirects from HTTP to HTTPS may also be desirable:

sudo nano /etc/nginx/sites-enabled/redirects.conf

(The redirect could have been added instead in  /etc/nginx/sites-enabled/static-www.example.com, though personally I like all of my https/www-type redirects for all sites in one file.)

It may also be a good idea to serve robots.txt on our “old” WordPress URL at admin.example.com, to prevent the indexing of anything under that domain:

sudo nano $location of www.example.com config$

Inside your server block, add the following:

location /robots.txt {
    return 200 "User-agent: *\nDisallow: /\n";
 }

Then, test the NGINX config and restart:

sudo nginx -t (correct any errors listed here)

sudo service nginx restart

The WordPress plugin “Simply Static” should now be installed, and configured in Simply Static>Settings so that it uses relative URLs (the path is simply “/”), and outputs to a local directory, set as /var/www/static-www.example.com/htdocs/.

Whenever the website is now updated, in order to push changes to production, “Generate” must be pressed under Simply Static>Generate.

If WordPress Multisite is being used, some further configuration may be required.

Caveats

The default WordPress commenting system will not work under this configuration; neither will many dynamic WordPress functions.

It is not the best system for WordPress sites with multiple authors.

But it’s all worth it in the end for the GLORIOUS SPEED!