So, you want to know how to make WordPress fast.
Speed matters. People are impatient. Especially people who use the internet. Every second a visitor is waiting is a chance for him to give up. He’s not going to sit around waiting for your site to load. He’ll just try another site. That means less revenue and more bounces. Google now considers performance in its page rank algorithm. If your site loads slowly, or if people are bouncing, Google lowers your rankings.
Can you make WordPress Fast? How much will that cost?
Here are 14 steps to make WordPress fast. If you have a little time, it’s not too difficult. It won’t break the bank.
There is more to speed than just hosting. A fast hosting provider is important. Very important. But you also need to optimize WordPress. If you sign up with an enterprise hosting provider, they will not launch your site until you do the optimizations I list below. But you need not pay thousands of dollars each month to get that speed. You can make a fast WordPress site for $20-30/month. Be prepared to switch your host and DNS provider if needed, and you’ll also need to set aside time to optimize WordPress.
It took me a lot of experimentation over the years to improve the performance of this website to where it is today. Knowing what I know now, it wouldn’t take more than an afternoon. On most pages b3n.org has a PageSpeed score 99 to 100 for Desktop users and 92-97 for mobile.
Below, you’ll find what I did to take this website from a score of 46 to 100:
The good news is, it isn’t too much effort and while you can spend some money; it doesn’t have to break the bank. Going from a score of 46 to 90 is easy. Getting to 100 will take some work; and you may need to sacrifice your favorite plugin. But you can do it.
Do you want to make your WordPress site fast? Read on.
What Makes WordPress Slow
- Dynamic Content Generation. WordPress generates content on the fly using PHP and MySQL. If your server isn’t powerful enough and you aren’t using caching, this will quickly bring a server to its knees.
- Un-optimized Images. Do you upload images to WordPress with little thought? They may be too large or in an inefficient format. You could spend hours optimizing each image. But who has time for that? I don’t. You don’t. Let’s find a WordPress plugin to do it for you automatically.
- Old, Slow, or Oversold Host. Your website host may have an old version of PHP, be limiting your bandwidth, have resource limits, have cheap hardware, or is oversold. Many hosting companies sell you a year of service for a discount and seem fast at first but get slower and slower the more their servers fill up.
- Render Blocking CSS, JavaScript, and Images. When a website loads you need not send and process every single image, CSS and JavaScript file to the visitor at once. Only what’s needed to render the page. The rest can come a few seconds later.
- Too much JavaScript and CSS. You may have way too many plugins adding bloat. This requires more CPU time on the browser to render.
- Your server is geographically too far away. If your visitor is in the United Kingdom and your server is in San Francisco you’re adding 150ms of round-trip time.
- Content served from too many domains. Each domain requires a DNS lookup and a new TLS negotiation (which requires several round trips if you’re not using HTTP/3) which adds up fast.
- Slow DNS. Your DNS provider may take several hundred milliseconds to respond and it may not be cached on the edge.
Here’s How I made WordPress Fast
Warning: Don’t destroy your production site. Before you get started, deploy a copy of your site to a staging environment. Or at the very least make a fresh backup. I use UpdraftPlus.
First, get a baseline by checking your website against Google PageSpeed or GTmetrix. Pick 2 or 3 URLs. Your home page and a blog post or two. Each time you make a change, check those 3 URLs using those site tools to make sure you’re not making it worse. Both sites can give you suggestions for improving performance. What I have written below not only addresses best practices mentioned on the above tools, but I’ve thrown in a few of my own.
Now, this site is not perfect. But I’m at the point I consider it 93% optimized… it loads faster than most other sites. If I wanted to spend time in the details there are a hundred little changes I could make to try to get that last 7%. But it would take me months—possibly years. It’s good enough. …for now anyway.
Here is a quick overview of what you must do to make WordPress fast with details to follow:
How to Make WordPress Fast
- Get a Fast Website Host
Get a fast server. Features to look for: LiteSpeed or NGINX+Varnish, LSPHP or PHP-FPM, Redis or Memcached, HTTP/2 or HTTP/3 QUIC.
- Install a Cache Plugin
Install a WordPress Caching Plugin.
- Use a Fast CDN
Use a CDN such as Cloudflare or Google CDN.
- Optimize & Lazy Load Images
Optimize your images. Serve WebP to browsers that support it. Lazy load images.
- Minify CSS, JavaScript, HTML
Every byte counts.
- Prefetch Pages
Install a WordPress plugin to prefetch pages before visitors click on them.
- Defer non-Critical CSS
Install a plugin to defer non-Critical CSS until after the page loads.
- Delay non-Critical JavaScript
Install a plugin to delay processing JavaScript that isn’t essential to render the page.
- Use a Fast DNS Provider
Use a fast DNS service such as Cloudflare.
- Setup Object Caching
Setup Redis or Memcached Object caching to reduce the load on your database.
- Lazyload Comments
If you have pages with hundreds of comments lazy-load them.
- Cache Gravatar images locally
Use a plugin to cache Gravatar images to save a DNS lookup and give you control of the image cache.
- Host Google Analytics Locally and Make it Smaller
Google Analytics is a big JavaScript file. More than you need.
- Remove Slow Plugins
Remove plugins that are bloated with CSS and JavaScript.
Get a Fast Website Host
There are several ways to get performance out of a web server:
- Fast Hardware. Lots of cores and memory on the latest hardware.
- Fast Software. Look for hosts using NGINX or LiteSpeed, newer versions of PHP, and MySQL, and some form of caching.
- Don’t use a host that’s oversold.
- Make sure they don’t throttle your bandwidth or impose resource limits.
- Usually (but not always) the term “Managed WordPress Hosting” is a good thing.
A few rules when choosing a web host:
- Don’t pre-pay for a year of hosting. Your performance needs may change at any moment and you don’t want to be locked into a vendor. With hosting the best flexibility is month to month (DigitalOcean charges by the second).
- Be wary of hosting companies owned by EIG (e.g. BlueHost). They oversell and get slower and slower. The reason you see other blogs recommend BlueHost is not because they are the best WordPress host, but because they have the best referral program.
What host do I use? | What IS the FASTEST WEB HOST?
So… I don’t use a web host. I just do it myself. I have a $15 DigitalOcean droplet. 2 cores. 2 GB memory, 3TB monthly transfer. Running OpenLiteSpeed (which is faster than NGINX according to WP Speed Matters), LiteSpeed Memcached, LSPHP74, and MariaDB. Now, this isn’t something I recommend to people who don’t have experience managing servers. I’ve been running web servers since High School so that’s what I do. If you’re comfortable doing that go for it. Otherwise find a fast hosting company and don’t get locked into a contract. If you want Managed WordPress on a DigitalOcean instance Cloudways is the best performance per dollar you can get with Managed WordPress hosting. I also like Cloudways’ ability to instantly clone your site into a staging environment. But feel free to find your own fast web hosting company.
What Region Should You Deploy a Server In for THE FASTEST PERFORMANCE?
Some hosting providers have a variety of regions. Don’t worry if your host doesn’t provide this option. But if given an option, always deploy near most of your visitors. That will give most people the lowest latency possible. I deploy my servers in one of DigitalOcean’s NYC data centers. Most of my visitors are from North America followed by Europe so that’s the closest central location for the majority of visitors. The location will not matter too much because of CDNs (more on CDNs below)… but it will help before your CDN is warms up.
There’s also some prudence here. Why would I choose New York or Virginia over Oregon or California? I like to have my servers far away. This makes it so a major disaster is less likely to take my site down and affect me personally at the same time. Perhaps this is overly cautious, but there is some logic to this.
The WordPress Caching Plugins
The first time b3n.org got on the front page of Hacker News and Reddit thousands of people were trying to hit the site all at once. My website broke. My server couldn’t keep up. Installing a caching plugin fixed this problem.
Without caching, dynamic content must generate for each visit to your website. Unless you have a lot of cores and memory, this will quickly overload your server. You need a caching plugin to generate that content once, save the cache to disk (or memory) and then visitors are just fetching the pre-cached page. Serving up a cached page costs your server virtually nothing.
If you have separate mobile and desktop themes be careful with caching. If a mobile user hits a page first, he will cause that version to get cached for everyone. While there are options in plugins to cache separate desktop and mobile versions of a page, the safest and best way to handle this is to use a responsive theme.
Here are 3 of my favorite WordPress Caching Plugins:
Breeze – Simple.
I call this the 80/20 plugin. If you don’t want to spend a lot of time tweaking settings, this is for you. Breeze is simple. It takes 20% of the effort to get 80% of the benefits. Install this plugin and your website will be faster. You’re done. I ran b3n.org on Breeze for a long time. The main reason I switched away from it is I wanted to optimize the last 20% such as deferring critical CSS and found that WP Rocket and LiteSpeed Cache were better than that.
WP Rocket – gold standard
It’s $50/year (renewal is discounted by 30%). This is the most popular WordPress optimization plugin. WP Rocket is an all in one package that does almost everything and will work in the widest number of scenarios. It’s hard to go wrong with WP Rocket. It requires minimal configuration but offers some advanced tweaking and works with a variety of configurations and webservers (Apache or NGINX). One reason I recommend this is it’s robust, mature, works everywhere, and is widely used so most problems you would run into have likely already been fixed. The pricing scales well. If you have several clients just grab a $250 license to install it on an unlimited number of sites.
LiteSpeed Cache – Complex bUT GOOD AND FREE
I’m using LiteSpeed Cache on b3n.org. It’s free, it is more comprehensive than WP Rocket. But… it only works with the OpenLiteSpeed or LiteSpeed webserver. It’s designed to have tight integration between WordPress, LiteSpeed’s cache, and many CDNs including Cloudflare. This plugin integrates directly with LiteSpeed’s memory cache. This is a lot faster than NGINX’s PHP caching. It also has tight integration with the QUIC.cloud CDN making it easy to push your dynamic content to the edge.
How do you know if caching is working? Look at the page source and at the bottom you will see something like this:
<!-- Page optimized by LiteSpeed Cache @2020-04-07 03:54:45 -->
<!-- Page generated by LiteSpeed Cache 2.9.9.2 on 2020-04-06 20:54:45 -->
And you will see this in the response header if LSCache is working:
X-LiteSpeed-Cache: hit
Get a CDN, a Good One.
Content Delivery Networks take the content from your website and store it on edge servers all around the globe. I use Cloudflare. What Cloudflare does is copies all my pages, images, JavaScript, and CSS files and caches them on their servers all over the world. They have 200 edge locations so chances are you’re less than 30 milliseconds away from b3n.org (ping it to see).
When you visit b3n.org from Tasmania, you’re not connecting to my server in New York City. Instead, you’re connecting to the nearest purple dot Cloudflare location, probably Melbourne.
(If you are the hypothetical guy in Tasmania, let me know how the speed is).
The Sucuri Performance testing tool allows me to test the site response time from all over the world. Pretty fast, I’d say.
What are the Fastest CDNs?
CDNPerf has a continually updated list of the fastest and most reliable CDN Services. The difference between 1st and 15th place is only 10ms, so there are plenty of options!
Why I use Cloudflare’s CDN
You notice that Cloudflare is not the fastest CDN. So why do I use it? It’s simple, free, has a lot of features, and is fast enough. Spending a lot of money to get another 6ms will not be noticeable. Cloudflare was one of the first CDNs to support HTTP/2 and HTTP/3 QUIC and they’re innovative—this company uses Lava Lamps (fluid dynamics) to generate entropy.
When you see a company with a wall of Lava Lamps, you know they take security seriously.
What sold me is the simplicity—most CDNs will change your image and JavaScript URLs to point at their address. Cloudflare runs your entire site through them (not just assets) meaning nothing changes as far as your URL structure.
It’s the easiest CDN to set up. After signing up for an account, they’ll walk you through these steps:
- Make Cloudflare your DNS server
- Point some records at your webserver’s IP address
- Turn on the proxy button in DNS …and you’re done. Your whole site now loads from Cloudflare.
By default, Cloudflare doesn’t cache dynamic pages (it just passes the request on to your server), but it’s simple enough to add a rule for it to do so. I added the 3-page rules from Gijo Varghese’s article on Caching WordPress Pages using CloudFlare Page Rules and my TTFB (Time to First Byte) on PageSpeed Insights went from 150ms to 30ms. I modified Gijo’s rules slightly to add additional security on the wp-admin page (as pictured below).
If you turn on Cloudflare page caching and browse to a page on your site while you are logged in to WordPress, Cloudflare may cache the admin bar (visitors can’t do anything bad, but they’ll see a bar). Because of this, you should switch Cloudflare to Development mode (under Overview or Caching in the web panel) whenever you log in to WordPress as admin. Alternatively, set the IP to your origin server in /etc/hosts to bypass Cloudflare locally.
Cloudflare 1000 Clients Per Second Test
Don’t try this at home. … or at least ask Cloudflare for permission.
I load tested my site on Cloudflare using Loader.io. This is the best way to see if a site can survive the Slashdot effect. I did a simulated load from 1 to 1000 Clients per Second sustained over 1 minute. The results…
You can see the response times scale linearly as number of clients increases and never goes above 30ms. Cloudflare responded to 1,684,397 requests and delivered 102.7 GB of data in 60 seconds! That would be a rate of 6TB/hour. That’s a decent load. There were zero response errors, network errors, or timeouts. 100% of the requests were responded to.
For the cost (none) it’s hard to beat. I have custom firewall rules, page rules, rate limiting, DDoS protection. All on the free plan. I know there are people with busier sites than mine using it as well.
While I use a CDN and it reduces the load on my server, my practice is to not rely on it. My DigitalOcean web server can easily handle the load without Cloudflare.
Other CDNs
If I didn’t use Cloudflare, I would be interested in trying out LiteSpeed’s QUIC.cloud (Beta) CDN Service because like Cloudflare it can also cache the entire website and because of its integration with LiteSpeed’s WordPress cache plugin. Also, Google’s CDN is considered the best, so that’s another one I would look into.
Optimize and Lazy Load Images
How to make images load fast:
- Optimize Images
Lossless optimization retains the original quality but reduces the size. - Lazy Load Images
Instead of loading every image on your page, Lazy Load only loads images as a user scrolls down. This is a huge bandwidth saver for those in rural areas. - Convert to WebP
WebP files can be 1/3rd the size of a PNG with similar quality. Google PageSpeed Insights will ding you for not using WebP. But the problem is IE and Safari don’t support WebP so if you serve WebP you need a way to fallback to PNG or JPG formats. - Bonus: Resize Images for Each Device
If a user on a mobile phone is visiting your site, you don’t need to deliver the full-sized image. While this may not improve your score, most people on mobile devices have limited bandwidth, so it’s important to not waste it. The one drawback to doing this if a person loads your site in a windowed browser then maximizes the window. The image will be too small. They must refresh to get appropriately sized images. This is an acceptable trade-off for me, but it won’t be on all sites.
Here are some WordPress plugins that will do this for you.
The Best WordPress Image Optimizer Plugins
So, I’ve tried many image optimization and lazy load plugins, most caused problems or didn’t work in edge cases. But the two plugins that cause the fewest problems for me are both made by ShortPixel. ShortPixel gives you 100 credits a month for free. Or you can buy 10,000 image credits for $10 and you can use credits with either of their plugins.
ShortPixel Image Optimizer
The ShortPixel Image Optimizer plugin is the best I’ve found for optimizing images locally. It also converts animated GIFs to WebP animations. You can optimize individual images, or do a batch optimization. It does the optimizations on their servers so no load on yours. It can do everything on my list except for number 4. It won’t resize images for each sized device. However, this is the cheapest option. Once you’ve optimized an image, it’s good forever so if you’re patient you can optimize your entire site for free using the 100 credits a month they give you. When I initially installed ShortPixel I had several thousand images that needed optimizing so I bought 10,000 credits, but then since I was adding less than 100 images a month it was free after that. But I ended up switching to their newest plugin…
ShortPixel Adaptive Images Plugin
The plugin I now use is the ShortPixel Adaptive Images plugin. It recently came out, but I switched to it because it solves all four problems above. It Optimizes Images on the fly converting them to WebP (even animated gifs) and serving those to every browser that supports WebP (visitors using IE or Safari will still be served JPG, PNG, or GIF files), and it generates appropriately sized images on the fly for the visitors’ specific screen resolution, and lazy loads. They charge you each time an image is optimized and will store it on their CDN. This plugin eats up more credits because credit is used up for each screen size, and because images expire after 30 days so they need to be re-optimized. I buy 10,000 credits at a time that’ll last 3 or 4 months so it costs roughly $3/month to use this service.
ShortPixel Adaptive Images uses Stackpath CDN. You can use that, or if you want to use their service behind Cloudflare’s CDN that’s also possible (that’s how I have it configured). I much prefer to put it behind Cloudflare so I can serve images from my domain, cdn.b3n.org instead of cdn.shortpixel.ai. I like to have that control.
LiteSpeed Cache Plugin
Of course, if you’re using the LiteSpeed Cache Plugin it has the capability of ShortPixel’s Image Optimizer Plugin built-in, but it’s entirely free. I’ve found that while it works with a bit of tweaking it was not as robust or easy to set up as ShortPixel.
Minify HTML, CSS, and JavaScript
You know, in the days of GZIP I think tidying up JS and CSS is overkill, but it helps with your PageSpeed score. This can be a long process, but you can use your cache plugin: Breeze, WP Rocket or LiteSpeed. Cloudflare can also do this for you. Start turning on Optimization and Minification options. Turn one on at a time until your site breaks, then skip that one and go to the next. Usually your caching plugin or Cloudflare can do a good job at this. But on some sites I’ve found it’s better to turn those optimizations off on the caching plugin and use Autoptimize instead.
Prefetch Pages
When a visitor hits your page, chances are she will click on another page. And what better way to be ready than to have every page she may click on prefetched and ready to go? Many plugins can do this (WP Rocket and LiteSpeed Cache have an option can do this) but the best by far and the one I use is Flying Pages…
Prefetching pages will not increase your PageSpeed score. It might even make it worse. But it will make your site faster for your visitors.
Flying Pages is a tiny JavaScript that will prefetch any links to other pages on your site. As your visitor scrolls down any new links that appear automatically get prefetched. Now when she clicks, the page was already fetched. Instant load! The reason Flying Pages is the best plugin is the author, Gijo Varghese, anticipated all the things that could go wrong when he wrote this. His plugin:
- Waits until the page is fully loaded and rendered before re-loading content.
- Limits the number of preloads per second so it’s not overloading the server or the user’s browser.
- Stops preloading if the server is busy
- Checks if the user has enabled data-saver or is on a slow mobile connection. If so it won’t preload anything.
- Only preloads what’s on the screen.
While this plugin can improve performance, remember that it will generate a lot of traffic to your site so I wouldn’t enable this unless your server can handle it. Make sure you have caching and a CDN setup first.
A side benefit to Flying Pages is your site visitors automatically keep your WordPress and CDN caches warm.
Defer non-Critical CSS
Normally a website will wait until it has received and processed all the CSS files before rendering a page. What you can do is determine which CSS is Critical to render the page above the fold (before the user scrolls down) and inline that into the HTML. This allows the browser to render the page without the CSS files. Then the rest of the CSS is delivered whenever. The result is rendering the page a few seconds sooner. This is tricky because you need to determine what the “above the fold” Critical CSS is. WP Rocket and LiteSpeed Cache are the only two plugins I know that automatically determine the Critical CSS and do everything for you. LiteSpeed Cache can figure out the Critical CSS for each page… useful if you have CSS active on some pages but not other. I use the LiteSpeed Cache Plugin to Generate Critical CSS.
Delay Non-Critical JavaScript
JavaScript parsing is not free so you can delay non-critical JavaScript until after the page has finished loading… this allows the browser to process only the JavaScript needed to render the page first, then it will process the rest. I use WP Speed Matter’s Flying Scripts Plugin which will let you choose which JavaScript files can be delayed. WP Rocket and LiteSpeed Cache have options to defer JavaScript, but the Flying Scripts Plugin does a better job.
Use a Fast DNS Provider | The Fastest One
Cloudflare is consistently the fastest DNS provider. I use Cloudflare’s DNS. According to DNSPerf Cloudflare is the fastest DNS provider in the World. If I lost 6ms by using Cloudflare instead of Google for a CDN, I more than gained it back using Cloudflare’s DNS.
Install an Object Cache
An Object Cache, for the purpose of this article, stores the results of database queries in memory to reduce the load on the database and reduces disk I/O. This improves the performance of repetitive queries against MySQL or MariaDB.
Many hosting providers will support either Redis or Memcached. If you’re using LiteSpeed or OpenLitespeed use LiteSpeed Memcached. If you’re using LiteSpeed Cache or WP Rocket just enable Redis or Memcache there and you’re good. If you’re using Breeze, you must find a plugin to take advantage of Object Caching.
Lazy Load Comments
I noticed that some pages still took a long time to render. Turns out that pages with 400 comments take a while to load. If you have pages with lots of comments, you need to Lazy Load Comments. The thing with comments is they don’t need to be sent unless your visitor scrolls down to read them. When he scrolls down, they load automatically.
The Lazy Load for Comments Plugin does just that. Once I installed that plugin posts with hundreds of comments load instantly.
Another plugin that can do Lazy Load comments is the Comments – wpDiscuz plugin. I don’t use this plugin because it is slower than native comments, but it’s popular so I included this trick in case you use it. It is not obvious how to enable Lazy Loading, so here’s the trick:
- Under wpDiscuz Settings -> Comment List Settings -> select “Lazy load comments on scrolling”. This does nothing until you complete step 2.
- In WordPress go to Settings -> Discussion. Make sure “Break comments into pages with [x] top level comments per page and the [first] page displayed by default” is NOT checked. But you must still enter a number greater than zero for x. (e.g. 5).
Cache Gravatar Images Locally
Gravatar is a service by Automattic, it gives everyone an online avatar. It is a universal place people can upload a profile image tied to their email address, and it becomes available on many websites. Having pictures of people and robots who comment on your blog posts enhances the experience. It’s worth it. The problem is, if you have 100 people who commented on a post that means your visitors are downloading 100 images from Gravatar. The best way to handle this is to cache those images locally using Harry’s Gravatar Cache. That will get the images behind your CDN instead of loading them from Gravatar’s site.
Host Google Analytics Locally
Google Analytics is heavy. The Flying Analytics Plugin will host it locally, and it also has a Minimal version at 1.5KB (instead of 44KB) which meets the needs of most webmasters.
Get Rid of Plugins You Don’t Need
This was hard—I like to display my Currently Reading Goodreads shelf, have Google Analytics, Amazon Affiliate links, CloudFlare Analytics, NewRelic analytics, Popular posts, Social Media icons, ConvertKit email forms, etc.
This was a hard decision for me but here’s what I did:
Delete! Delete! Delete!
- I took off the Goodreads widget. Not only did it pull images from offsite, but Goodreads doesn’t even send a cache header… and it made multiple calls on different domains to get the data! Sadly, I disabled it.
- NewRelic. Gone. I don’t need it running all the time.
- Popular Posts. I was using JetPack’s Popular Posts, and it had to re-generate entirely in JavaScript on each page load—it was the largest delay on my site. Gone. I now use a different Popular Posts plugin that generates in PHP instead of JavaScript.
- Social Media Icons. Gone.
After implementing everything above, my PageSpeed store was still between 80 and 85 for most pages.
And finally, we get to JetPack. You’re going to have to turn it off. Arg. JetPack, JetPack, JetPack… I love JetPack. It provides good features. But it’s bloated and the main reason my blog was slow because of all the client-side processing. Do I disable it or not? Google considers performance in their page ranking …and I can’t just ignore Google. Most people find my posts through a Google search. I spent some time trying to tune JetPack and even found plugins that try to clean it up. Even with half the features turned off JetPack was eating up a ton of resources, loading Emojis when I wasn’t using them, adding unnecessary JavaScript, loading files with no cache-control from multiple WordPress domains, etc.
After being unable to optimize it, I finally just turned it off. That was hard. My site is no longer connected to Automattic (I prefer JetPack’s simple page stats to Google Analytics). Now nobody can “Like” my posts. The one feature I didn’t want to lose was the ability for people to subscribe to comments by email. I found Subscribe to Comments Reloaded which meets that need. After I disabled JetPack I purged LiteSpeed’s cache. Then I purged Cloudflare’s cache.
And after that last change, something amazing happened….
My WordPress Performance
For the first time, Google PageSpeed ranked me at 100.