Improve WordPress Performance, a real world example. How this was implemented on a website to reduce WordPress page load times, pass core web vitals, improve user experience, gain improved rankings, increase traffic, and extend engagement times.
The task: Improve a WordPress Website’s Performance
I was given the task of addressing some problems with a website. The problem that had been noticed was that the mobile menu toggle button would periodically fail. You’d click it and it wouldn’t do anything. Given that mobile device usage is more prevalent, this was a problem that really needed to be addressed.
When I took a look at the website I noticed that there were more problems with the site. I used google’s page speed insights and tolls.pingdom.com as mentioned on our blog post about website analysis tools to gain a quick oversight of problems with the website.
The main problems were:
- Mobile menu doesn’t dsplay
- Slow page load times
- Failing core web vitals
- A page weight of 4.8 MB (of which 1.8 MB is JavaScript over 49 individual scripts)
- A large amount of thread work
- Long LCP time
- Cumulative layout shift
- Outdated image formats
- Render blocking resources
- Unused CSS
- Unused JavaScript
- 39 CSS files
- 49 JavaScript files
The google page speed insights report was as follows:
And the tools.pingdom.com report was as follows:
First steps
The site in question was being hosted in one of our Unlimited Web Hosting packages. This aligns with our WordPress Hosting package.
We’ve undertake quite a lot of work with the underlying stack to improve performance so I knew that the following were available:
- Litespeed web server
- Object caching
- Opcache
- HTTP/3
- Brotli Compression
Because I knew the above was in place, I was fairly sure that we weren’t looking at an issue with the hosting, which meant that I’d have to investigate by looking in to the WordPress side of things.
As I didn’t want the live site to be affected while I carried out the required work, the first thing I did was clone the website to a subdomain using the softaculous facility (this is available in all the hosting accounts we provide). I also used a robots.txt to prevent the cloned site from being indexed while I carried out the work, as I didn’t wan to cause any content duplication problems with search engines.
Mobile menu doesn’t display when burger menu is clicked.
JavaScript minify and combine being enabled in the NitroPack caching plugin.
Cause identified by:
Using chrome developer tools to identify browser errors, respective scripts being served from a cache directory. Purging the NitroPack’s cache and disabling JavaScript minify and combine resolves the issue.
Course of action:
Remove NitroPack plugin. I’d heard some slightly unnerving things about this plugin, and I’m sure I’d read a review of it as well.
This plugin was also configured to minify, combine and Asynchronous loading. The Effect of this was that the initial render of the page took place before 0.25 MB css file was downloaded (funnily enough). What this means is that an initial page draw takes place, then the CSS is applied and a secondary page draw takes place. As the layout of the second page draw differs from the first, content layout shift takes place.
I also wanted to use the Litespeed cache plugin to leverage the full benefit of the underlying litespeed web server, object caching, opcache and brotli compression. This plugin can also be used to convert images to webp format, which helps with reducing page weight. The Litespeed cache plugin can also be used to optimise CSS and JavaScript.
Problems with page output:
- 1.8 MB is JavaScript
- Excessive main thread work
- Render blocking resources
- Unused CSS (contributing, but not all)
- Unused JavaScript (contributing, but not all)
- 39 CSS files (contributing, but not all)
- 49 JavaScript files (contributing, but not all)
The cause of the problems with page output:
WP bakery / visual composer
Cause identified by:
Using chrome developer tools network waterfall to identify JavaScript paths, and sizes. Using chrome developer tools to identify high work functions.
Course of action:
Disable WP bakery. The problem with this is that visual composer uses a lot of PHP shortcodes to generate page elements. If you disable WP bakery, the function behind the shortcode is also disabled. The appearance of the page then changes from what looks like a web page to a jumble of shortcodes and text. On the plus side, this did significantly reduce page weight, thread work, and the amount of JavaScript/.js files being called on page load.
Problem as a consequence of disabling WP bakery:
Pages appear as jumble of short codes and text.
Cause of problem as a consequence of disabling WP bakery identified by:
Seeing this problem immediately after disabling WP bakery.
Course of action:
Rework all website pages using the built in blocks editor in WordPress. Yes, you read that right. I had to manually rework all website pages manually, making the appearance like for like so that visitors perceived the website to be the same in appearance. This was quite a lot of work (there were around 90 pages with the blog included), but there’s not really any way round this, or a quick way of getting this done. I just had to bite the bullet with this one, as I couldn’t really optimise 1.8 MB of JavaScript that was already minified.
It’s amazing how much difference a page builder can make. This situation was quite extreme. Not all page builders have such a big effect on website performance. The problem with page builders is that you often won’t know how much effect they have until you’ve built a page. As you can see from the above, sometimes you might need to remake a whole website.
There’s a really easy way to avoid this page builder problem, and to eliminate the “will it be a problem?” and that’s to not install a page builder plugin. If you do use a page builder plugin, you may find yourself in the position where you’re addressing issues, or optimising content that simply wouldn’t be present if you weren’t using a plugin based page builder.
The blocks editor in WordPress is now very usable, and using this avoids a lot of problems with page output.
Problems causing delays with browser rendering:
- Render blocking resources
- Unused CSS (contributing, but not all)
- Unused JavaScript (contributing, but not all)
Cause of probelms with browser rendering:
Theme / WordPress bloat
Cause identified by:
Using chrome developer tools network waterfall to identify file paths. Using the treemap in google page speed insights to identify unused CSS and JS. Using the “opportunities” in google page speed insights to identify render blocking scripts.
Course of action:
Change theme, optimise later using Litespeed cache plugin. Use the unbloat plugin to remove WordPress bloat.
Changing the theme did involve manually rebuilding the header and the footer, which is a bit of work (although not as much as rebuilding 90 pages). I opted to use Kadence as the new theme, as I know it performs well, has minimal overhead, and provides fully featured header and footer customisation facilities. It was these that allowed me to make the site header and footer appear consistent between the old and the new websites.
Problem with Largest Contentful Paint (LCP):
Long LCP time.
The cause of the problem with Largest Contentful Paint (LCP):
Lack of preloading LCP images, no image optimisation undertaken, same image being called for both mobile and desktop.
Cause identified by:
Reading page source, chrome developer tools network waterfall. Debug bear’s website speed test.
Course of action:
Make optimised images for all header images (one for desktop, one for mobile) using an image editor on my computer. Use stackable’s column element for page headers (this allows for device specific images – one for desktop, another for mobile). Use the preload LCP image plugin to preload each image on a device specific basis.
Final Problem:
Me being dissatisfied with results so far.
Cause of final problem:
High standards.
Course of action:
Litespeed cache plugin. This plugin is a winner when it comes to improving performance. In most cases (although please check your site after making these changes, should you do so). All you need to do is:
- Install and activate this plugin
- Request a domain key in the “general section” wait until it’s been generated then click on “automatically update” then save changed
- Click on Cache > Object
- And enabled object caching (redis if you can)
- Click on Presets > Apply (in the “Advanced (Recommended)” column)
- Click on Page Cache > Media > On (next to “Lazy Load Images”) > Save changes
- Click on Image optimisation and set:
- Auto Request Cron: on
- Auto Pull Cron: on
- Optimise Original Images: on
- Image WebP Replacement: on
You’ll need to wait for all images to be updated to Webp format as this works on a push pull basis, so can take a bit of time, especially if you have an image heavy site.
One of the things that’s quite clever about this caching plugin is that it integrates with the quic.cloud CDN (this is what the domain key part does). Although you’re not truly using the quic.cloud CDN with the config above, what quic does is reads your site, optimises your page output (specifically CSS and JS) in to tiny combined files, pushes them to a local cache, and then uses these on page load thereafter.
What this means is that you get a great deal of effective script based optimisation done for you, rather that a using multiple plugins to achieve a similar result.
The results are in!
After carrying out all the above:
- Page weight decreased from 4.8 MB to 464 KB (over a 90% reduction in data transfer)
- Total size of CSS decreased from 253 KB to 24 KB
- Number of CSS files decreased from 39 to 4
- Total size of JS decreased from 1.8 MB to 2 KB
- Number of JS files decreased from 49 to 2
- A page speed insights performance metric (mobile) increased from 28 to 95
- FCP time dropping from 3.9s to 1.4s
- LCP time dropping from 9.9s to 1.5s
- Blocking time dropping from 1930 ms to 190 ms
- CLS dropping from 0.11 to 0.044
- The majority of issues flagged by page speed insights are addresses
And most importantly, the site now passes core web vitals.
Screen shots showing the above in page speed insights and tools.pingdom.com are below.
I then used softaculous to push the site to live. “Which site was this?” I hear you ask. Why dear reader, it was the website you’re lookng at now.
If you’d like us to do the same for your WordPress website, we offer a Website optimisation service to cover this work.
Here’s the page speed insights report after the above was carried out:
Here’s the tools.pingdom.com report after the above was carried out: