How to speed up your WordPress site, fast!
Here at BrightMinded, we use WordPress for two main reasons: our clients love it as a Content Management System (CMS), and as developers, we can extend it in pretty much any way we can dream up. However, it’s fair to say that when we first came across WordPress in 2011, we weren’t immediately enamoured. We found the WordPress database structure a bit odd, and we weren’t convinced about the way the core code was written.
There are still, shall we say, quirks with WordPress, and only the most blinkered evangelist would argue that it’s the best tool for every web project. However, one claim we sometimes hear is that it’s too slow, so let’s debunk that myth by taking you through nine proven ways to speed up WordPress! There may be elements of truth in the accusation for a default WordPress installation, but one of the great selling points is that we can take that default installation and make it our own. After years of working with WordPress, we’re experts in speeding it up beyond all recognition, and in this post, we’ll share our experiences.
Why does the speed of your site matter? The obvious reason is that your visitors will get bored waiting for a slow website to load, and may go elsewhere. The other important point is that Google uses page speed as part of its search ranking algorithms. In other words – the faster your site is, the better chance it has of ranking higher in the Google search results.
Let us take you through nine proven WordPress optimisation methods that will keep your visitors, and the search engines, happy.
1. Hosting
It’s worth making clear that there are two flavours of WordPress: hosted and self-hosted. At BrightMinded we deal only with the self-hosted version. We download the latest version of the open-source code, and we’re then free to add our themes and plugins, or even modify the core code (perish the thought)!
If you’re not confident hosting your site then you might be more comfortable using the hosted WordPress.com version, the downside is that most plans place restrictions on the themes and plugins available. We may be biased, but we think you should talk to BrightMinded and get the best of both worlds — enjoy the flexibility of the self-hosted version, but leave the hosting and maintenance headaches to us.
We host each of our clients on their own dedicated virtual server, meaning there is no competition for resources from other websites or applications running on the same server. This is the first step in ensuring that you have a fast WordPress site — make sure that your hosting is up to the job.
2. Plugin proliferation
One reason why WordPress has become so popular is that non-developers can find plugins to do just about anything they need without having to write a line of code. The downside to this approach is that the number of plugins in use can quickly grow. We’ve seen sites with more than 50 plugins activated, sometimes providing only a few lines of useful code.
As a rule, code from every activated plugin is executed with every request to the site, so the more plugins there are, the slower the site runs. There are other problems as well — managing the upgrades and security patches for a large number of plugins places a high burden on the site administrator.
Also, the more plugins you have installed, the higher the chances of a conflict between two of those plugins. The site administrator is then reliant on multiple third-party plugin developers to diagnose the problem, agree on a solution, and resolve the issue.
When we build a WordPress site, we don’t assemble a collection of third-party plugins. We take a handful of well-tested, industry-standard plugins with excellent support, and then we build the rest of the site from scratch. This allows us to make sure that all the functionality works nicely together, and keeps the upgrade burden manageable. It also ensures that the only plugin code executed on our sites is providing functionality that our client needs, without any bloat.
We sometimes get asked to rescue sites which have ground to a halt, or in some cases even been hacked, because they are weighed down with third party plugins. If you have a legacy site which fits this description, why not talk to us about making it fast and secure?
3. Page caching
Those familiar with WordPress will know that out-of-the-box, the content for each page is stored as a single database field. That’s all very well, but we like to offer our clients flexible pages with a variety of drag and drop modules. And unlike complex page-builders, each module has simple, nicely structured custom fields to make it easy to enter just the content needed for that particular module. No generic lumps of content requiring developer skills in our themes!
Behind the scenes, WordPress stores each of these custom fields as a separate row in a metadata database table. To construct a page for a site visitor, each of these rows must be read from the database, and then the content combined into the full page. This potentially involves a large number of database reads, which could be slow.
Enter page caching: fast, cheap and under control!
The basic idea is to read the fields of content from the database and construct the page, but then store the complete page as a static HTML file. This static HTML is then served to subsequent visitors, resulting in a massive speed gain.
We don’t need to reread the content from the database until a page editor next changes the content from the dashboard. When that does happen the rows are reread, the new version of the page is constructed, and a new static HTML file is stored and served to subsequent visitors.
Over the years, we have experimented with writing our page-caching plugin and used a few third-party ones as well. The one we’ve settled on is WP Rocket — it works well out-of-the-box but also has those all-important hooks which allow us as developers to tailor it to the needs of each project.
This is useful because each site needs a slightly different caching strategy. It doesn’t usually make sense to cache “My Account” or checkout pages, for example, which should show different information to each user, or each session. Editing the content on one page might also have knock-on effects on other pages.
For example, if a new blog post is published, all pages which promote the most recent blog post should also have their cached versions rebuilt. If necessary, we can mix the speed gains of caching with the benefits of dynamic content using Ajax. To achieve this, we cache the majority of the page but use JavaScript to call out to the server to fetch some dynamic content to insert into the page.
This is probably the single most crucial action point if you wish to speed up your WordPress site — so start caching!
4. Concatenation
As we build WordPress themes for complex sites, there are often multiple JavaScript and CSS files involved, each adding a specific bit of functionality. This is how we like to develop — it is much more manageable than having one huge file to maintain. However, browsers need to make a separate HTTP request for each file, and this can be an expensive operation. The HTTP connection request might take longer than the file data transfer.
To minimise this overhead we concatenate all the JavaScript files together, and all the CSS files together — a small but significant speed up. We do this as part of our build process, but there are also plugins available to help, for example, Autooptimize.
Concatenation is not always appropriate — sometimes different code is required on different pages with little overlap. In that case, it might make sense to keep the files separate. Google also suggests separating the resources which are required to render what a visitor sees ‘above the fold’ (at the top of the page) to speed up loading the most visible area of the page.
5. Minification
Experienced developers give variables and functions descriptive names, and format their code to make it readable. This helps the original developer remember what their code does, and supports all those who have to understand and maintain that code into the future.
(Arguably sometimes they go overboard. David did some interesting analysis of JavaScript function names in public GitHub repositories. As part of this he extracted the longest function names and found some beauties, including this one which won’t fit on the page…:
Despite this, the point remains that functions and variables should have names that humans can understand, and files should be formatted to make them easy to read.)
However, computers don’t care about fancy function naming conventions and formatting. Your browser cares only about being able to identify and call the correct bit of code – everything else is irrelevant. All that our lovingly crafted function names do is increase the amount of data which must be transferred from the server to the browser, slowing down the loading time of the page.
Therefore we “minify” all resources, stripping out whitespace and comments so that file sizes are smaller. To go one step further, we can replace function names and variables with the shortest possible identifiers — meaningless to us but just as useful to the browser.
We do our concatenation and minification using Gulp tasks to automate our pre-processing before we deploy our code to staging and production environments.
Here’s an example of a snippet of JavaScript written for developers to understand:
var accordionItem = $(this).closest('.accordion');
if (accordionItem.hasClass('closed')) {
rotate(accordionItem.find('.icon-open'), 'open');
}
This can be minified down to the following:
var a=$(this).closest('.accordion');if(a.hasClass('closed')){rotate(a.find('.icon-open'),'open');}
6. Compression
After our build process has concatenated and minified the files in our WordPress theme, we get the server to compress them before delivering them to the browser. The most popular compression method is called Gzip, and all modern browsers can work with resources compressed in this way. Gzip works well where there is lots of repetition, so it is ideal for compressing resources such as HTML and CSS where there are likely to be many instances of the same tag or keyword repeated within a file.
As a rule of thumb, Gzip compression can achieve at least a 70% reduction in file size, so this is an essential step in speeding up your site delivery. It’s also an easy change to your Apache web server configuration which doesn’t require putting in place any additional build tools.
7. Image optimisation
Often the images on a web page are the largest component in terms of the page size. Crisp, detailed images can make a website, especially if you are sitting on a wealth of stunning wildlife photography as our clients at the British Ecological Society are. The downside is that the browser must download those images, and they can be huge! Luckily there are ways to mitigate this.
Custom image sizes
WordPress has a great drag-and-drop media library, making it easy to manage all the images for your site in one place. The handy feature from a performance perspective is the built-in support for custom image sizes. This allows us to resize images appropriately for the context in which they appear.
For example, an image accompanying a blog post might appear as a full-width banner on the blog post itself, but a small thumbnail when it is used to promote the post on the “Latest News” page. WordPress lets us define the appropriate pixel sizes and cropping rules for the image in each context, and the editor needs only upload the image once — WordPress does the rest.
Pagespeed server module
As we noted above, Google loves websites which are quick to load. Their reasons may not be entirely altruistic, but they provide a good range of tools to help developers speed up their sites, so we’re not complaining.
One which we use on all our new sites is their modpagespeed module for Apache (they also support the Nginx web server). This module offers a wide range of filters which will optimise various aspects of delivering your site to your visitors’ browsers.
Pagespeed provides filters to carry out loads of tasks, including the minification and concatenation mentioned above (which we’re doing with our Gulp tasks). One which we always enable is the “Optimise Images” filter. This filter is fully configurable but also has an excellent default configuration out-of-the-box using the rewrite_images filter group. This will compress your images, convert them to an optimal image format, and even change the dimensions to the size at which they will be rendered.
8. Browser caching
We mentioned page caching above, which is where we do some optimisation on the server to speed up delivery to the browser. There is another important type of caching we can leverage, but this time browser-side. We can use HTTP headers to instruct the browser to cache images and other static resources. This means that next time a page is viewed, the browser will use its cached versions rather than requesting the resource again, speeding up the page load.
To achieve this, we can use either the “Expires” or “Cache-Control: max-age” header. Here’s an example of an Apache .htaccess snippet which tells browsers to cache JavaScript files for 31 days before requesting an updated version.
# Cache JavaScripts for 31 days
<filesmatch ".(js)$">
Header set Cache-Control "max-age=2678400, private"
One important consideration here is what happens when you update your static resources and need the browser to fetch the updated version. If you change your JavaScript, for example, it’s not good if your visitors’ browsers are hanging on to the old file with the same name, but without the new functionality. What we do to get around this is version all our WordPress theme and plugin resources using the time each file was last modified on disk:
$version = date('mdYHi', filemtime('my/dev/path/js/main.min.js'));
wp_enqueue_script('main-js', 'https://example.com/path/js/main.min.js', array(), $version, true);
This means that as soon as we deploy a change to our JavaScript file, browsers will request the latest version and then cache that updated version.
9. Disabling unnecessary features
WordPress is a big piece of software with lots of features. Not all of it is necessary for all of our clients, and it makes sense to disable anything which isn’t needed. Preventing unnecessary code from being executed will speed things up for our site visitors and administrators.
A concrete example of this is the WordPress custom fields metabox, which will be familiar to you if you’re a WordPress aficionado:
Custom fields allow us to structure our content more nicely, as we touched on in the section above on page caching. However, we don’t need this metabox because we handle custom fields with a much better interface, using structured field groups tailored to each type of page.
Furthermore, to display and populate this metabox, WordPress needs to read all the custom field data from the database. On a complex site with many custom fields, this can be an expensive operation and can, therefore, slow down the page editor for our site administrators.
Our site administrators are just as important as our end users, so Bradley wrote a simple plugin to remove this metabox and speed things up for them. If you’re developing your WordPress site and would like to try it out, you can install his plugin from the public repository.
We hope that this post has given you some useful suggestions for speeding up your WordPress site. If you have any questions or suggestions for us or would like us to speed up your website for you, please get in touch!