wordpress optimization fast load time

WordPress Optimization with WHM cPanel PHP7

Running high traffic sites means WordPress optimization is crucial. I spend a lot of time reading, thinking, and testing configurations to constantly improve the performance of my WordPress sites, as well as the server load. When sites are getting over 100,000 visitors per month, every millisecond counts. Whether you are running a blog, enterprise site, or local business, ensuring your visitors and customers have a fast speed can make all the difference between someone who clicks away and someone who stays for a while. This post is formatted in a way which starts with the lowest hanging fruit and gets harder and more complex the farther down you read. Begin your WordPress optimization from the top and begin measuring results!

If you’re reading this and realize its simply more than you feel comfortable taking on, or want to hire a WordPress optimization expert, send me a message for hire and I’d be more than happy to speed up your website!

Last Updated: June 14, 2016

Disclaimer: This post includes affiliate links for some of the products mentioned, however, I am not being compensated to endorse any of the products. 

WordPress Web Hosting

The first step in WordPress optimization is choosing a good web host.As a web developer, I’ve used and been exposed to a huge variety of web hosts. I’m ultra-picky and want the very best available for my budget. I use iWFHosting.

A lot of people running WordPress website are going to be on what’s called “Shared Hosting” plans. While these are not inherently bad, a lot of times web hosts overload the amount of customers on a single server, causing a slowdown for everyone. With the amount of sites and traffic I handle, I’m beyond the shared hosting spectrum. I run a VPS, or virtual private server. Running a VPS allows me to quickly scale on demand, as well as better manage backups and testing configurations.

Beyond Hosting – A CDN for WordPress

With a good web host selected, the next step is getting a content delivery network, or CDN setup. I ended up with MaxCDN for several reasons. The first being a lot of plugins support integration with their API. The second being their support and speed were excellent. I’ve bugged them multiple times with silly questions and their expertise has always proved worthwhile. With a Pull Zone setup, these are the ideal settings I’ve found for a WordPress site running SSL/HTTPS.

WordPress Optimization

With a good server setup in place, now we can move on to actual WordPress optimization. The first step is getting some plugins in place to do some automated tasks. Then, we’re going to analyze what the WordPress site is currently loading, and then install a few more plugins and optimize the theme.

WordPress Plugins to Help Auto Optimize

Better WordPress Minify
This minifies and combines your CSS/JS files, and works with MaxCDN. Combining files equals less HTTP requests and a faster load time. Once the automatic configuration is in place and the rest of the optimization of this section is complete, you’re going to want to come back and revisit the advanced and enqueued files section to start moving scripts to the footer and test until something breaks. Moving js files to the footer means portions of the site won’t stop displaying as scripts download and render. These are the settings I am currently using on this site.

Comet Cache
This is one of the best automatic non-configuration-required caching plugins I’ve found and used. If you have users visiting your site whom are logging in, you’re going to need the Pro version. This is a common pro feature across a lot of caching plugins. For everyone else, these are the only options you’ll need, and this is what will display in the source code:

wordpress optimization comet cache

EWWW Image Optimizer
Optimizes all of your images and PDFs into the smallest size possible without sacrificing quality. This means your assets will load much faster. The only settings I usually touch on this plugin are Deferred Optimization and I use a bit more intense optimization levels. This is so I can work on posts and upload images faster, and I know when my wp_cron (will get to this soon) runs every hour, the images will be optimized.

wordpress optimization ewww image optimizer

Heartbeat Control
WordPress has an API that autosaves drafts which by default goes every 15 seconds. This plugin lets you change the frequency to every 60 seconds. There is an option to disable where it runs, but I kept it everywhere so future plugins or features aren’t affected. I could totally see myself spending an hour trying to figure out why a plugin doesn’t work, only to realize its a setting here.

wordpress optimization heartbeat control

WP-DBManager
Over time, junk data accumulates in the database. This plugin can automatically run an optimize and repair command every set amount of days – I do 3 days – and helps keeps database requests running smoothly. I ran an optimize command on a client’s site that had been running for several years without any maintenance and got the database size from around 90 megabytes to under 10. That’s a lot of junk. You can also use this to run automatic backups of the database.

wordpress optimization automatic mysql database optimizing

Analyzing Your WordPress Performance

Head over to either GTMetrix or Pingdom. Or, do both and see how the different companies analyze your site, cause you’re just as particular as me.

wordpress optimization analysis

This is what a typical graph will look like as I optimize a WordPress site, testing as I go. I was already familiar with my own site, so the process didn’t take as long, but it generally takes anywhere from 2-6 hours to optimize a WordPress site before even getting to the server itself.

Going off the GTMetrix waterfall view or the Pingdom File requests view, the first thing I look for is how many fonts are being loaded. A lot of times themes or plugins load multiple themes. Your site should have a consistent brand and look, so this will accomplish several things. Removing extra fonts from loading will improve your branding, as well as reduce the number of requests for your site to load.

Next, look for any 404 errors that are popping up. Go and find out what is missing, and fix those. For example, in testing this site, I realized I had a 404 image that was causing a huge slowdown. Oops.

I like to check out the 200 response code request. This is going to be the first one in the list and the most crucial. This is also where caching will shave off a lot of time.

Keep analyzing the waterfall as you go, and take care of different items that seem out of place to you. Try playing with BWPM to get to the ideal configuration.

Remove, minify, or modify one item at a time, flush your cache, and retest. If something breaks, its easy to undo what you just changed, versus guessing over multiple items. This is the most tedious of the entire process and takes a lot of close scrutiny. You’ll also have a much better understanding of how your website works and dependencies when you’re done.

High Traffic Websites and wp-cron.php

Every time a visitor goes to your site or loads a page, wp-cron.php is triggered. This is WordPress checking to see if it needs to do anything. This includes checking for updates, scheduled posts, email notifications, or a number of other tasks. When your website is getting several thousand or more hits per day, this uses up resources unnecessarily. Disabling the default wp-cron.php will be a lifesaver.

Open wp-config.php and add the below code. I usually place new code near the debug function.

define('DISABLE_WP_CRON', 'true');

optimize wordpress wp_cron

Now, login to cPanel and setup a Cron Job to hit wp-cron.php every hour. Change the username to your cPanel username and make sure the path is correct, especially if you’re on a subdomain or subdirectory.

cd /home/CPANELUSERNAME/public_html; php -q wp-cron.php

optimize wordpress cpanel wp-cron php

Database Bloat and Revision Control

Every time you save a post, WordPress saves a version of that post in the database. These are all accessed via the Revisions interface. WordPress will keep saving every version indefinitely. I got up to 48 revisions on this post alone in writing the initial spec. Figuring out an appropriate number of revisions for your style and setting that will reduce the size of the database. I personally set mine to 7 via wp-config.php:

define('WP_POST_REVISIONS', 7);

Miscellaneous WordPress Notes

Too many plugins equals a slow site – This is a false myth. I currently have 50 active plugins on this site, and another 20 or so which are inactive. I get load times in under 3 seconds, and often under 1 second.

wc-ajax=get_refreshed_fragments – This is something which will show up as a slowdown if you’re running WooCommerce or haven’t installed the Heartbeat Control plugin. Its probably a bad idea to disable completely. I run WooCommerce on this site, and the only way to speed it up significantly is to disable the ajax-cart option here: /wp-admin/admin.php?page=wc-settings&tab=products&section=display

Remove extra fonts being loaded – If you can’t find where fonts are being loaded, or if the theme is loading extra fonts on its own, removing them via BWPM is the way to go.

Themeforest themes are slow – Would you be surprised to learn I am using X and a child theme? Sure, there are bad themes out there, but it isn’t always the theme causing slowdowns.

cPanel WordPress Optimization

Optimize Website – This generically named setting is where you can enable compression/gzip of your content.

wordpress optimization cpanel compress gzip mod_deflate

For the more advanced readers – Zlib for compression is another good option when configuring WHM, although I’m not sure what PHP7 support is.

While not directly related to WordPress speed, its a good idea to make sure your DKIM and SPF records under Authentication are valid. These records help fight spam and let’s other mail servers know that your e-mail is authentic.

wordpress optimization cpanel dkim spf

Advanced WordPress Optimization

Alright, time to take a break, make a fresh brew of coffee, and get ready to dive into the heavier and more advanced areas of getting the most performance out of your WordPress website.

advanced wordpress optimization

Disclaimer and notice of imminent danger: Modifying settings in WHM could very well render your enter server useless. This guide includes items which can break stuff. If you feel unsure of a setting, or want a better understanding, ask your web host support or search for more information. I am only providing a very superficial overview on many of the following items. WHM supports Dry Runs of some of these settings, particularly EasyApache – take advantage of this, even if it takes you longer.

My current setup is a VPS with 8G Ram, 4 Xeon CPU cores, SSD drive, SolusVM, CentOS 6.8, and WHM56. If your setup is radically different, you may encounter problems. Feel free to ask your web host if these settings are safe.

WHM WordPress Optimization

There is a lot to adjust within WHM. I’m going to go down the menu and just list changed settings related to WordPress performance. There are plenty of other settings you may want to change for security, or based off of a specific website environment.

If there is another setting within WHM I missed which has impacted your WordPress performance, comment with an explanation and let me know to add it. Most of the heavy lifting was done prior to this point, and now that we are in WHM/PHP configurations, I’d love to have some input from others on further performance tuning.

Again, only settings which have been changed from their default and related to WordPress optimization are listed here.

WHM Tweak Settings

Compression
gzip compression level: 6
pigz processes: 4
Kb per chunk: 128

Mail
Initial default/catch-all: Fail
Email delivery retry time: 60m
Enable BoxTrapper spam trap: Off
Enable Mailman mailing lists: Off

Stats Programs
Enable Analog stats: Off

System
File upload required free space: 128MB

Apache Configuration

Global Configuration

Piped Log Configuration:
Enable Piped Apache Logs

PHP7 Configuration

As of the time of writing this post, PHP7 and EasyApach4 are not quite released for production. According to support, EA4 is ready for 95% of the people. Based off outstanding bugs, I felt they didn’t affect my usage, therefor it was reasonably safe to upgrade. If you read this and you’re running WHM 58, then EA4 is ready for you!

EasyApache4

To install EasyApache4, follow this link. If something goes wrong, you’ll want to follow the same link to uninstall.

Below is my current configuration. I did not include versions for security reasons. I’m probably using whatever is listed as the latest.

Apache MPM
ea-apache24-mod_mpm_worker

Server Modules – You might recognize the names deflate, expires, and headers from your caching plugin.
ea-apache24-mod_bwlimited
ea-apache24-mod_cgid
ea-apache24-mod_deflate
ea-apache24-mod_expires
ea-apache24-mod_headers
ea-apache24-mod_proxy
ea-apache24-mod_proxy_fcgi
ea-apache24-mod_proxy_http
ea-apache24-mod_security2
ea-apache24-mod_ssl
ea-apache24-mod_suexec
ea-apache24-mod_suphp
ea-apache24-mod_unique_id

PHP – I kept PHP5.5 and PHP5.6, even though I plan on using PHP7, in case I need a fallback. I’ll phase out PHP5 in the future.
ea-php55
ea-php56
ea-php70

PHP Extensions
ea-php70-build
ea-php70-libc-client
ea-php70-pear
ea-php70-php-bcmath
ea-php70-php-bz2
ea-php70-php-calendar
ea-php70-php-cli
ea-php70-php-common
ea-php70-php-curl
ea-php70-php-dba
ea-php70-php-devel
ea-php70-php-enchant
ea-php70-php-exif
ea-php70-php-fileinfo
ea-php70-php-fpm
ea-php70-php-ftp
ea-php70-php-gd
ea-php70-php-gettext
ea-php70-php-gmp
ea-php70-php-iconv
ea-php70-php-imap
ea-php70-php-intl
ea-php70-php-ldap
ea-php70-php-mbstring
ea-php70-php-mcrypt
ea-php70-php-mysqlnd
ea-php70-php-odbc
ea-php70-php-opcache
ea-php70-php-pdo
ea-php70-php-pgsql
ea-php70-php-posix
ea-php70-php-process
ea-php70-php-pspell
ea-php70-php-snmp
ea-php70-php-soap
ea-php70-php-sockets
ea-php70-php-tidy
ea-php70-php-xml
ea-php70-php-xmlrpc
ea-php70-php-zip
ea-php70-runtime

Plus a similar config for 5.6 and 5.5.

PHP Configuration / MultiPHP INI Editor

Basic Mode

max_execution_time: 180
max_input_time: 60
max_input_vars: 3000
upload_max_filesize: 32M

Editor Mode

; Opcache Tuning
opcache.revalidate_freq=0
opcache.validate_timestamps=0 (comment this out dev environment)
opcache.max_accelerated_files=7963
opcache.memory_consumption=192
opcache.interned_strings_buffer=16
opcache.fast_shutdown=1

Whew! You made it to the end. Please comment if:

  • This helped you in any way – post screenshots of your results from Pingdom or Gtmetrix!
  • I missed something
  • You have a better config to share

Sources

 

Comments 18

  1. Hi,

    Great information here, I love reading about other webmasters efforts to achieve page speed optimizations.

    I did have a couple questions.

    Why not use W3 Total Cache or WP Rocket for example to do your minify and cache functions in one plugin versus two separate? I know most people new to W3 have a hard time with the settings etc, however, once you understand that plugin you really can do a lot in a very short period of time. WP Rocket also is a great solution (depending on host) that runs all that you mentioned right out of the box with one plugin.

    In regards to WP-DBManger, I highly endorse that plugin as well, I love it and makes working with the DB so much easier.

    In the cPanel/WHM section, do you find that the compression messes with the minification of elements on your sites or have you not run into any issues in that regard?

    1. Post
      Author

      Hey Clint,

      I’m so glad you brought up W3TC! That plugin used to be my default and I had a couple configs I imported based on the type of site and was pretty happy. However, on some sites I discovered W3TC was slowing down logged in users to a crawl to the point where productivity was horrid. I started exploring other cache plugin options and settled on Comet Cache. Its done a spectacular job on the highly trafficked sites and is very friendly to not needing configuration. I don’t think I tried WP Rocket, but now I’d be interested in checking it out compared to CC. One thing CC cache does well is integrates with my CDN, without any additional setup or configuration. It seems to provide an awesome balance of function with ease of use. What’s your experience on backend speed with W3TC?

      The compression in cPanel doesn’t make a difference – its a bit of redundancy with the plugins used, but it also ensures any files outside of WordPress get compressed. If people are hardcoding links to images/etc in theme files, cPanel will ensure the files are compressed.

      Mike

      1. We have not seen any slow downs on membership sites with W3TC like you have, however we are not doing 100K logged in users either so there is that.

        There is that setting to disable caching for logged in users, however, if it’s a site where a logged in user could comment for example then I can see where that function might defeat the purpose.

        Either way, it certainly is something to look at more closely on larger sites.

        Clint

  2. Thank you for sharing your insights which is obviously the result of a crazy amount of work over a long period of time. You are going to save a lot of people a lot of grief! Just one comment on cache plugins – I’m using WP Rocket and I have found it to make a huge difference (like it better than all the others I have tried including W3TC, but I have not used Comet. I’m currently debugging an issue on one site that might be cache related but other than that, Rocket has been great.
    For image compression I typically use Photoshop and the ‘Save for web’ option and THEN further compress the image via the website: http://tinypng (which will do jpgs too).
    Google maps slows down a page I find and has some issues. I usually replace the map with a static image and a button. Way faster.

    1. Post
      Author

      Hi Glenn,

      You’re the second person to mention WP Rocket. I am very curious how it stacks against Comet now. I “save for web” first, too.

      That is a great point about Google Maps – most uses don’t require a dynamic map. An image with a button or image map is usually sufficient and much faster. It just feels so easy to embed that iframe!

      Mike

  3. Call this a third query for WP Rocket. They’re a paid plug-in, which is perhaps why there’s this curiosity if a free plugin does the job better than a paid one.

    Also, caution about minifying JS, especially if you’re running plugins like Gravity Forms or noticing issues with your theme. Moving JS to the footer can also cause issues.

  4. Pingback: 3 Takeaways from the IFBC Blogger Conference - Sacramento BloggersSacramento Bloggers

  5. Great post mate, enjoyed working through the steps and cross checking my own new EA4 setup.
    Turns out something fundamental on my server was broken though…no idea what.

    I upgraded to EA4, php7 (stripped the others), and used above config and hit provision…

    Now the sites seem fine but trying to add a plugin to a WordPress site is resulting in the dreaded “To perform the requested action, WordPress needs to access your web server. Please enter your FTP credentials to proceed. If you do not remember your credentials, you should contact your web host.”

    Did the usual chown command and…nada…still broken.

    Been at it for hours now.

    Decided to provision a new server and move my sites over to it as this is driving me nuts (wish I had the time to faff and fix, sadly it’s a time consuming process so went for easier option)

    But again, great post :)

    1. Post
      Author

      Oh man, that sucks. I realize you already made the change, but did you try setting up the update process to use SSH instead of FTP in the wp-config? There is an awesome blog post here: http://www.acme-dot.com/set-up-wordpress-to-install-plugins-update-itself-and-upload-media-via-sftp-without-passwords/

      I also have no idea what seems to cause that – I’ve had it happen a couple times and re-doing the account has fixed it.

      Did you follow my config on the new server without issues?

      Thanks for the feedback!

  6. Some great info here, thanks a bunch especially the php7 list I had missed a couple! I have been messing around with a basic wordpress install to see what kind of performance I can get.

    Couple notes relating to my WHM Centos 6.8 and PHP7:

    WIth php7 some of the settings files locations are changed from what I have found anyways…, eg:

    opcache options are set in opcache.ini in /opt/cpanel/ea-php70/root/etc/php.d
    apcu options in a php.ini file in /opt/cpanel/ea-php70/root/etc

    As for a caching plugin I found the simplest and most effective for my site to be Cache Enabler by KeyCDN
    Don’t forget about autoptimize and async javascript plugins too.
    Thanks again!

    https://www.dropbox.com/s/k6jp7zrl3lqnshx/Screenshot%202016-11-09%2017.07.09.png?dl=0

    1. Post
      Author

      Nice load times!!! Have you checked a before/after with those javascript plugins to see impact? So happy this helped you. Thanks for sharing your additional findings.

    1. Post
      Author

      Yes, that would be great. Quote away and send me the link when its published. I’m going to play around with autoptimize and see what kind of impact I find on this site and some others.

  7. Great post, thank you.
    Yip. must also add autoptimize in the list. Has been great on my site.
    Also using snippets plugin, to disble emojis, remove share counts (big saving), remove query strings, load only the font awesome essentials filter.
    also async javascript plugin.
    Also use webpagetest.org… seems to give the most conservative loading times.
    Also use wp optimize.
    I know how you feel things can get very frustrating… (my blog posts vanished a few hours ago in my dashboard for instance)…. but got my 100% google page speed and 99% yslow on gtmetrix.

    It’s as a result of being anal… because the site used to be a little go daddy $5 website on their website tonight and get tons of leads and traffic. Which was actually as a result of content being written for the target market. Whereas now all the fiddling hasn’t achieved what the result should be… other than the joy in getting the 100% score.

  8. Great article. We’re using WP Rocket for optimization.

    I have a question though, does the Heartbeat Control plugin have the same function with placing the line below to our wp-config.php?

    define(‘AUTOSAVE_INTERVAL’, 120);

    1. Post
      Author
  9. I notice you use suPHP and also FCGI, so which do you choose in your PHP Handlers section? I assume CGI to enable OpCache? is this still secure as suPHP for shared hosting environment?

  10. Thank you, good detailed list wished I’d know about this a long time ago. I have to ask though, you mention as short list of the elements you have activated in Apache, I assume those are all the ones that are not active by default? As it’s a very short list, or do you mean you only run exactly those on their own? I’m still working with an earlier version of Apache, so I haven’t got a reference point as those aren’t in my current Easyapache set up. Or at least the naming scheme is different enough, to not make it obvious barring a few which are replacements for which. It’s confusing because some you listed are active by default, but the list itself looks way too short.

    Kind Regards

Leave a Reply

Your email address will not be published. Required fields are marked *