A slow WordPress site loses visitors and Google rankings. A fast site starts with NVMe hosting and proper cache configuration.
1. Page Caching
Install a caching plugin — this is the most important improvement:
- WP Rocket — the best (paid, $59/year). Includes everything out of the box
- LiteSpeed Cache — free, ideal on LiteSpeed servers
- W3 Total Cache — free, flexible configuration
2. Image Optimization
# Convert to WebP via a plugin:
# ShortPixel, Imagify, or WebP Express
# Or via the command line:
sudo apt install webp
cwebp -q 85 image.jpg -o image.webp
Additionally:
- Install the Smush or ShortPixel plugin for compression without quality loss
- Add the
loading="lazy"attribute — WP 5.5+ does this automatically - Use correct sizes: don't upload a 4000px image for a 300px thumbnail
3. CSS and JS Minification
In WP Rocket: enable Minify CSS files and Minify JavaScript files.
A free alternative is the Autoptimize plugin.
4. Cloudflare CDN (Free)
- Sign up at cloudflare.com
- Add your domain → Cloudflare will provide NS servers
- Replace the NS records in your domain settings at your registrar
- Enable Caching → Caching Level: Standard
5. PHP 8.2 Instead of 7.4
In cPanel → PHP Versions, switch to PHP 8.2. Performance gain — up to 30%.
Optimization Results
| Before Optimization | After Optimization |
|---|---|
| LCP: 4.8s | LCP: 1.2s |
| PageSpeed: 42 | PageSpeed: 91 |
| Page size: 3.2 MB | Page size: 0.8 MB |
Common mistakes when speeding up WordPress
Aggressive optimization without understanding the cause breaks a site more often than it speeds it up. Let's look at typical mistakes.
Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 20480 bytes) in /wp-includes/class-wp-image-editor-imagick.php on line 226
This error shows up during bulk thumbnail regeneration or WebP conversion via wp media regenerate or the ShortPixel plugin: PHP hits its memory_limit (usually 256 MB on hosting) while processing large source images. Fix it by raising the limit in php.ini to 512M for the duration of the conversion, or process images in batches of 50-100 files.
Invalid command 'AddOutputFilterByType', perhaps misspelled or defined by a module not included in the server configuration
This Apache log entry means the mod_deflate module isn't enabled on the server while the rule is already in .htaccess. Without <IfModule mod_deflate.c> the site fails with a 500 error right after the file is saved — wrap compression directives in a module check, as in the example above.
Caching plugin comparison
| Plugin | Price | Setup | LiteSpeed cache | Complexity |
|---|---|---|---|---|
| WP Rocket | $59/year | Automatic | No | Low |
| LiteSpeed Cache | Free | Partial | Yes | Medium |
| W3 Total Cache | Free | Manual | No | High |
LiteSpeed Cache only reaches its full potential on servers running the LiteSpeed web server — on Apache or Nginx some features (like ESI) are unavailable, and the gap with W3 Total Cache disappears.
When speed optimization won't help
Page caching doesn't save a WooCommerce store: the cart, checkout, and account pages are always dynamic and can't be fully cached — they need an object cache like Redis for WordPress, not just a page caching plugin. If TTFB is already above 600 ms on a blank page with no plugins, the problem isn't WordPress — it's an overloaded hosting plan or a slow disk; caching speeds up repeat visits but doesn't fix the root cause. Page builder plugins (Elementor, Divi) add their own CSS/JS on every request — minification shrinks file size, not the number of server requests.
How to verify the result
PageSpeed Insights alone isn't enough — it shows both Lab Data (a single run) and Field Data (real visits over 28 days), which can diverge. Check both metrics and TTFB directly:
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://example.com/
curl -I https://example.com/ | grep -i "cache\|content-encoding"
Look for Content-Encoding: gzip or br in the headers, and cache indicators such as X-Cache: HIT or cf-cache-status: HIT. If the headers don't change after enabling the plugin, the cache didn't activate — check for a conflict with another caching plugin or with Cloudflare settings.
On shared-CPU plans, neighboring sites create periodic load spikes that page caching doesn't smooth out — moving to a plan with guaranteed resources helps there, not another plugin. The bottom line on ordering: fix the root cause of slowness first (heavy plugins, an outdated PHP version, no caching at all), and only then add a CDN and minification — done in the reverse order, the effect is noticeably weaker and doesn't last.