According to Builtwith.com, WordPress holds close to 50% of the CMS share of the world’s top 1,000,000 websites. As for the ecommerce sphere, we’re at 33% with WooCommerce. And if we cast a wider net, percentages go higher. Although we may complain that WordPress can get bloated, resource-heavy, and its data model leaves a lot to be desired, there is no denying that WordPress is everywhere.
WordPress can thank its simplicity and a low barrier to entry for this pervasiveness. It’s easy to set up, and requires next to no technical knowledge. Hosting for WordPress can be found for as little as a couple of dollars per month, and the basic setup takes just a half hour of clicking. Free themes for WordPress are galore, some with included WYSIWYG page builders.
Many look down on it, but in many ways we can thank WordPress for the growth of the internet and PHP, and many internet professionals have WP’s gentle learning curve to thank for their careers.
But this ease of entry comes at a cost. Plenty of websites that proudly wear the WordPress badge were not done by professionals but by the cheapest developers. And often, it shows. Professional look and professional performance were afterthoughts.
One of the main points of feedback the owner of an aspiring high-quality website will get from a grudging professional is that performance and a professional look and feel shouldn’t be afterthoughts. You can’t easily paint or stick them over a website. Professional websites should be premeditated.
Above, a famous UK used car dealer, Ling’s Cars, tried a unique way to make a kitsch marketing punchline. Unless you’re REALLY sure about what you’re doing, DO NOT try this at home
And this starts with…
Choice of Hosting
Typically, new users will go with products that are on the low-cost side, with most of beginner-friendly bells and whistles. Considering the shady business practices by some big industry players in this arena, and the complaints and demands for site migration professionals coming from clients, this is a part of website setup that requires due attention.
We can divide WordPress hosting vendors into a few tiers.
Premium, WordPress-dedicated vendors like Kinsta whose plans start at $100 per month, or even higher-grade managed hosting like WordPress VIP by Automattic, may be worth their salt, but also may be out of reach for many website owners.
Medium tier Flywheel, A2 hosting, Siteground and Pantheon are among those considered reliable and performance oriented, offering acceptable speed and a managed hosting service for those more price-conscious. Users here may get a bit less hand-holding, but these services usually strike an acceptable balance between a solid setup, price, and options for more advanced users. Not to forget, there is Cloudways, which is a hybrid between VPS and managed hosting. Those with their audience in Europe may look into Pilvia, as it offers a performant server stack and is pretty affordable.
There’s an interesting survey of customer satisfaction with more prominent hosting vendors, published by Codeinwp.
For those of us not scared of the command line, there are VPS and dedicated-server vendors like Digital Ocean, Vultr, Linode, Amazon’s Lightsail, Hetzner in Europe, and OVH. Hetzner is a German vendor known for its quality physical servers on offer, somewhat above the price of virtual servers, while OVH offers very cost-efficient virtual servers. For the price-conscious, OVH’s subsidiary Kimsufi in Europe and Canada also offers bargain physical dedicated servers, and Host US has very affordable virtual servers.
With managed hosting, things to look for are a good server stack, good CDN integration, and of course SSD storage. Guaranteed resources, like with A2, are a big plus. The next thing to look for is SSH-access. Tech-savvy users may profit from WP-CLI availability.
When choosing a VPS, the thing to look for is XEN or KVM virtualization over OpenVZ, because it mitigates the overselling of resources, helping guarantee that the resources you bought are really yours. It also provides better security.
Easy Engine is software that can make your entire VPS/WordPress installation a one-hour job.
Regarding the server stack, Nginx is preferred to Apache if we’re pursuing performance, and PHP 7 is a must. If we really need Apache, using Nginx as a reverse proxy is a plus, but this setup can get complex.
WordPress 4.1 executed 95% more requests per second on PHP 7 compared to PHP 5.6.
When choosing your hosting, be aware of negative experiences with some providers that have become notorious.
The golden rule here is: don’t use it unless there’s a good reason to.
This may seem like a rule coming from the mouth of Homer Simpson, but if you can skip any of the bells and whistles, do so. Be conservative. If you must add some shiny functionality or JS eye candy, always prefer those tailored and coded as specifically as possible for your exact need. If you’re a skilled coder, and the project justifies the effort, code it yourself with minimalism in mind.
Review all the plugins your website can’t live without — and remove the others.
And most importantly: back up your website before you begin pruning!
If you have a theme where you use a lot of custom posts or fields, be warned that a lot of these will slow down your database queries. Keep your data model as simple as possible, and if not, consider that WordPress’ original intended purpose was as a blogging engine. If you need a lot more than that, you may want to consider some of the MVC web frameworks out there that will give you greater control over your data model and the choice of database.
If you know your way around the code, inspect your theme to find unnecessary database queries. Every individual database trip spends precious milliseconds in your TTFB, and megabytes of your server’s memory. Remember that secondary loops can be costly — so be warned when using widgets and plugins that show extra posts, like in sliders or widget areas. If you must use them, consider fetching all your posts in a single query, where it may otherwise slow down your website. There’s a GitHub repo for those not wanting to code from scratch.
Meta queries can be expensive
Using custom fields to fetch posts by some criteria can be a great tool to develop sophisticated things with WP. This is an example of a meta query, and here you can find some elaboration on its costs. Summary: post meta wasn’t built for filtering, taxonomies were.
get_post_meta is a function typically called to fetch custom fields, and it can be called with just the post ID as an argument, in which case it fetches all the post’s meta fields in an array, or it can have a custom field’s name as a second argument, in which case it returns just the specified field.
get_post_meta()for a certain post multiple times on a single page or request (for multiple custom fields), be aware that this won’t incur extra cost, because the first time this function is called, all the post meta gets cached.
Installing and deleting various plugins, and changing different themes over the lifetime of your website, often clutters your database with a lot of data that isn’t needed. It’s completely possible to discover — upon inspecting why a WordPress website is sluggish, or why it won’t even load, due to exhausted server memory — that the database has grown to hundreds and hundreds of megabytes, or over a gigabyte, with no content that explains it.
wp-options is where a lot of orphaned data usually gets left behind. This includes, but is not limited to, various transients (this post warns of best practices regarding deletion of transients in plugins). Transients are a form of cache, but as with any other caching, if misused, it can do more harm than good. If your server environment provides it, wp-cli has a command set dedicated to transients management, including deletion. If not, there are plugins in the WordPress plugins repo that can delete expired transients, but which offer less control.
If deleting transients still leaves us with a bloated database without any tangible cause, WP-Sweep is an excellent free tool that can do the job of cleaning up the database. Another one to consider is WP Optimize.
Before doing any kind of database cleanup, it’s strongly recommended that you back up your database!
One of the plugins that comes in very handy for profiling of the whole WordPress request lifecycle is Debug Objects. It offers an inspection of all the transients, shortcodes, classes, styles and scripts, templates loaded, db queries, and hooks.
After ensuring a sane, performance-oriented setup — considering our server stack in advance, eliminating the possible bloat created by theme choice and plugins and widgets overload — we should try to identify bottlenecks.
If we test our website in a tool like Pingdom Speed Test, we’ll get a waterfall chart of all the resources loaded in the request:
This gives us details about the request-response lifecycle, which we can analyze for bottlenecks. For instance:
- If the pink DNS time above is too big, it could mean we should consider caching our DNS records for a longer period. This is done by increasing the TTL setting in our domain management/registrar dashboard.
- If the SSL part is taking too long, we may want to consider enabling HTTP/2 to benefit from ALPN, adjusting our cache-control headers, and finally switching to a CDN service. “Web Performance in a Nutshell: HTTP/2, CDNs and Browser Caching” is a thorough article on this topic, as is “Analyzing HTTPS Performance Overhead” by KeyCDN.
- Connect, Send, and Receive parts usually depend on network latency, so these can be improved by hosting close to your intended audience, making sure your host has a fast uplink, and using a CDN. For these items, you may want to consider a ping tool too (not to be confused with the Pingdom tools mentioned above), to make sure your server is responsive.
- The Wait part — the yellow part of the waterfall — is the time your server infrastructure takes to produce or return the requested website. If this part takes too much time, you may want to return to our previous topics of optimizing the server, WordPress installation, and database stack. Or you may consider various layers of caching.
To get a more extensive testing and hand-holding tips on improving the website, there’s a little command line utility called webcoach. In an environment with NodeJS and npm installed (like Homestead Improved), installing it is simple:
npm install webcoach -g
After it’s been installed, we can get detailed insights and advice on how to improve our website’s various aspects, including performance: