Speeding up your Wordpress site in 2018

Conor

Elite Member
Joined
Nov 7, 2012
Messages
3,621
Reaction score
6,217
So I'm aware there are a couple of threads on this topic already, and a few of them contain some great information too.

However, there are a few tricks I've picked up over the years I thought I'd share. So, first things first:

Why bother speeding up my site?

Well, aside from the fact that no one likes waiting for things, it does apparently give you a slight SEO boost. It's a fairly simple process once you get the hang of it, so why not? We all like slight SEO boosts, right?

What's the first step?

I'm going to be explaining as if we're dealing with an old, slow site that needs a bit of new life breathed into it. We can start with the images. Just this step alone will often have a huge impact on your load time, because a few uncompressed photos can easily bring your site from less than 1mb to 5mb in size.

Download a tool called "FileOptimizer": https://nikkhokkho.sourceforge.io/static.php?page=FileOptimizer
It should be able to compress 1000+ images in bulk within a few hours (depending on the compression level you've chosen, I always opt for the highest). You'll want to download your entire /wp-content/uploads/ directory via FTP and just drag all your images into the program and let it do its thing. Once finished, your directory structure should stay intact, and you can just drag your optimised uploads folder back onto the server via FTP again.

Why not use a plugin such as Smush or EWWW?
Because I prefer not to. Some people have reported great results with them, I haven't seen such results. It's up to you though.

Browser Caching and Compression

This one depends on your server, but should work fine on Apache servers with mod_deflate enabled. I don't know all the jargon here, so I won't try sound smart. Basically, this code should work on the average Wordpress site. Stick it into the top of your .htaccess file:

Code:
# BEGIN Expire headers
<ifModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 604800 seconds"
  ExpiresByType image/x-icon "access plus 18144000 seconds"
  ExpiresByType image/jpeg "access plus 18144000 seconds"
  ExpiresByType image/png "access plus 18144000 seconds"
  ExpiresByType image/gif "access plus 18144000 seconds"
  ExpiresByType application/x-shockwave-flash "access plus 18144000 seconds"
  ExpiresByType text/css "access plus 604800 seconds"
  ExpiresByType text/javascript "access plus 604800 seconds"
  ExpiresByType application/javascript "access plus 604800 seconds"
  ExpiresByType application/x-javascript "access plus 604800 seconds"
  ExpiresByType text/html "access plus 604800 seconds"
  ExpiresByType application/xhtml+xml "access plus 3600 seconds"
</ifModule>
# END Expire headers


# BEGIN Cache-Control Headers
<ifModule mod_headers.c>
  <filesMatch "\.(ico|jpe?g|png|gif|swf)$">
    Header set Cache-Control "public"
  </filesMatch>
  <filesMatch "\.(css)$">
    Header set Cache-Control "public"
  </filesMatch>
  <filesMatch "\.(js)$">
    Header set Cache-Control "private"
  </filesMatch>
  <filesMatch "\.(x?html?|php)$">
    Header set Cache-Control "private, must-revalidate"
  </filesMatch>
</ifModule>
# END Cache-Control Headers

<IfModule mod_headers.c>
    # Serve gzip compressed CSS files if they exist
    # and the client accepts gzip.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.css" "$1\.css\.gz" [QSA]

    # Serve gzip compressed JS files if they exist
    # and the client accepts gzip.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.js" "$1\.js\.gz" [QSA]


    # Serve correct content types, and prevent mod_deflate double gzip.
    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
    RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1]


    <FilesMatch "(\.js\.gz|\.css\.gz)$">
      # Serve correct encoding type.
      Header append Content-Encoding gzip

      # Force proxies to cache gzipped &
      # non-gzipped css/js files separately.
      Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>

# Enable gzip compression for text, html, javascript, css, xml:
<IfModule mod_deflate.c>
    <IfModule mod_headers.c>
        Header append Vary User-Agent env=!dont-vary
    </IfModule>

    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/json
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/xsd
    AddOutputFilterByType DEFLATE text/xsl
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/x-js
    AddOutputFilterByType DEFLATE text/richtext
    AddOutputFilterByType DEFLATE text/svg+xml
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE image/svg+xml

    AddType image/svg+xml .svg
    AddType x-font/otf .otf
    AddType x-font/ttf .ttf
    AddType x-font/eot .eot
    AddType x-font/woff .woff
    AddType image/x-icon .ico
    AddType image/png .png

    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4.0[678] no-gzip
    BrowserMatch bMSIE !no-gzip !gzip-only-text/html

    <IfModule mod_mime.c>
        # DEFLATE by extension
        AddOutputFilter DEFLATE js css htm html xml
    </IfModule>
</IfModule>

# Specify a Vary: Accept-Encoding header
<IfModule mod_headers.c>
<FilesMatch "\.(js|css|xml|gz)$">
Header set Vary: Accept-Encoding
</FilesMatch>
</IfModule>

This code includes stuff like expiry times for fonts and pretty much every other file extension you'll find on a Wordpress site. I didn't write it myself, I just pieced it together from a bunch of different places.

Recommended Plugins

Autoptimize and WP Super Cache. In fact, just Autoptimize should do the trick if you want to cut down on plugins during the speed optimisation process. Basically we need to compress our CSS, Javascript and HTML, which is tricky to do manually, so may as well let a plugin handle it for us.

Which boxes do I tick?
These should do the trick on your average WP site:
  • Optimize HTML Code?
  • Optimize JavaScript Code?
  • Also aggregate inline JS?
  • Optimize CSS Code?
  • Also aggregate inline CSS?
  • Inline and Defer CSS?
  • Save aggregated script/css as static files? (Should already be ticked)
  • Also optimize for logged in users? (Should already be ticked)
  • Go to the "Extra" tab and tick "Remove emojis" and "Remove query strings from static resources", as long as it doesn't break anything important on your site.
A couple of things to keep in mind:
  • jQuery is amazing, but it doesn't like being deferred or sent to the footer. If your pretty sliders or contact forms stop working, you may want to add /jquery.js to the "Exclude scripts from Autoptimize" field.
  • I only discovered this one recently: The Google Pagespeed tool loves making life difficult for people. You can compress and inline your entire CSS library, only to be told to "Optimize CSS Delivery". You can easily get rid of this stupid error with the following tool: https://jonassebastianohlsson.com/criticalpathcssgenerator/. Basically, you'll want to copy your entire combined CSS file into the tool, and it'll generate only the "Critical" css required for your site to display properly. You're then free to defer the rest of your CSS in Autoptimize, pasting the "Critical" CSS into the box that appears when you tick the "Inline and Defer CSS?" box.
  • Remove Google Fonts. Or at least, tell Autoptimize to do it, under the "Extra" tab. But what if I want to use Google Fonts, because Arial looks like ass? You can just navigate to https://fonts.googleapis.com/css?family=YOUR-FONT and just copy paste everything on that page into your CSS somewhere. It'll get rid of the "Remove render blocking CSS" message in Google Pagespeed, at least.
That's that!

You must know that some of these steps won't work on some sites. You may need to tweak some things here and there, but most of the stuff here will work on most WP sites.

Final final notes
  • A lot of people don't realise how big a role hosting plays in the speed of your website. Please, please consider decent hosting if you're planning on actually having decent speeds. None of the things I've listed here will likely improve your server response time. I'm not saying you need to buy a $100/month dedicated server. Shared hosting will often work fine, but just make sure it's with a good company, and not Hostg*tor, or some crappy free hosting, for example.
  • I've mentioned Google Pagespeed a couple of times above, but I do recommend utilizing other tools concurrently, such as http://tools.pingdom.com/fpt/, to check different stats and make sure you're optimising the right stuff.
 
Last edited by a moderator:
By the way, I'm aware I posted the first block of "Expire headers" twice in the htaccess code. Just omit one of them. I can't edit my post now.
 
For larger sites install Redis cache on your server then install the plugin, redis cache and wp rocket. Awesome info :)
 
Thanks for the info, it looks great. I appreciate the information about Google fonts.
 
Have done everything you recommended and can't get load time under 3 seconds. Shared hosting is the bottleneck. Recently got an account at Vultr but am not geek enough to figure out how to use it yet. Without C panel it's a steep learning curve. Will need to figure it out if I want under 1 second load times.
Btw, what is considered acceptable load speeds?
 
Great post as always @Conor!

While you're at it, you can also install SSL on your site to enjoy the Benefits of H2 protocol aka HTTP/2. It will drastically improve the page load time. The reason for the requirement for the SSL is currently no browser supports HTTP/2 unencrypted.

Here's https://gokulkrishh.github.io/performance/2017/04/30/comparison-of-http-and-http2.html for someone who'd like to delve deep into the benefits and benchmarks.

http://www.http2demo.io/ how faster the resources from your site will load if it's transferred through H2 protocol.
 
Great post as always @Conor!

While you're at it, you can also install SSL on your site to enjoy the Benefits of H2 protocol aka HTTP/2. It will drastically improve the page load time. The reason for the requirement for the SSL is currently no browser supports HTTP/2 unencrypted.

Here's more info for someone who'd like to delve deep into the benefits and benchmarks.

This is how faster the resources from your site will load if it's transferred through H2 protocol.

Great advice, and actually another reason to make sure you choose the right server, as it's not always something that will just work off the bat, as far as I can tell: https://httpd.apache.org/docs/2.4/howto/http2.html
 
By the way, I'm aware I posted the first block of "Expire headers" twice in the htaccess code. Just omit one of them. I can't edit my post now.

Edited it for you :-)

Nice guide by the way and nice tip re the file optimiser tool always used the plugins in the past, but this tool sounds easier and probably cheaper or free I’m guessing?

For larger sites install Redis cache on your server then install the plugin, redis cache and wp rocket. Awesome info :)

Wp rocket is the best plugin I’ve used for improving overall load times.
 
but this tool sounds easier and probably cheaper or free I’m guessing?
Great to see you with the mod status Dave, congrats! Thanks for the edit too. The tool is totally free, always being updated too so you're getting the latest compression algos, which is nice :D
 
This is great info thanks alot. I am just working on WordPress site and the site speed is one of the main things left to work on. At 3 secs right now Android I think it's mainly because of the amount of CSS and js files. Going to try the automize plugin.
 
This is great info thanks alot. I am just working on WordPress site and the site speed is one of the main things left to work on. At 3 secs right now Android I think it's mainly because of the amount of CSS and js files. Going to try the automize plugin.

I definitely recommend using the critical path CSS generator I mentioned above, alongside Autoptimize. It definitely helps a ton when you've got a lot of CSS files like you do.
 
I definitely recommend using the critical path CSS generator I mentioned above, alongside Autoptimize. It definitely helps a ton when you've got a lot of CSS files like you do.

Yea I'm going to try that tomorrow and will post.back how much time it saved on load. Thanks
 
Ok so I gave autoptimize plugin a go as well as using a critical css generator to load priority css. Which did end up bringing my load time down. I also ended up compressing some random images being used which save about 300kb. So now my site is showing in average of 1.8 sec but it takes about 4.5 sec for the site to fully load. This is due to a stupid facebook plugin I'm using that has a ton of JS (simple facebook plugin). I should get rid of it but I need to have a facebook inline page showing up as well.

All in all doing the autoptimize, critical css, and image resizing saved third of the time for the page showing up.
 
The biggest bang for your buck isn't all of these optimizations. The biggest bang for your buck is putting the host that's serving your pages as geographically close to the majority of your users as possible.
 
Website has been very slow last week. Thanks to Godaddy. After a few tweaks and three agents , it's "suddenly" working fine
 
Conor! You've killed it!

Thank you for posting this, i was actually looking through some searches and this by far is a nice updated one!

Cheers
 
Back
Top