How to Score 100 on Google PageSpeed Insights: A Complete Guide to Optimizing Your WordPress Site Performance and Speed

Introduction

You don’t want visitors to your site to become frustrated because it takes too long to load. You also want to please Google and the other search engines; having a fast, responsive, and optimized WordPress site can help in that regard.

I recently decided it was finally time to update this site and to convert my other old, hand-coded, websites to WordPress. In the process I had to learn a lot about the platform, choose a theme, find useful plugins, and learn how to optimize WordPress for speed and performance. Years ago I had attempted to optimize my site with W3TC, but although that was very helpful I never got stellar results. That is mostly because I was focusing on only one tool without really understanding all the factors involved in optimizing a WordPress site. So, as I learned more about how WordPress works, I decided it would be an interesting challenge to see if I could get a perfect score on Google PageSpeed Insights. Well, I did it and now I want to share what I learned with you.

If you are reading this, you are probably at least somewhat familiar with some of the topics I will discuss in this loooong tutorial and, more specifically, you have probably heard about and maybe already used Google’s PageSpeed Insights tool to check your site’s overall performance. If so, you have almost certainly been frustrated with warnings given and are looking for ways to get rid of those and increase your score.

Regardless of your knowledge level, I hope this guide will give you a better understanding of what’s involved in optimizing a WordPress site’s speed and performance. I will also show you ways to improve your site enough to ace Google’s demanding test.

In This Article

What is the Goal?

Before getting started, I think we should stop and ask ourselves a fundamental question: what exactly are we trying to accomplish? Is the goal simply to please Google and hopefully reap SEO rewards for doing so? Is it a personal mission to get a perfect PageSpeed score at all costs? Is the goal to offer the very best user experience possible? It is likely a combination of all these things and, in theory, getting a great score should do the job, but life is complicated and in the real world sometimes there are decisions that need to be made which pit performance against usability and functionality. Knowing where and how to draw the line for these tradeoffs is not a science and will depend on your (and your audience’s) preferences.

Can You Really Score 100 on Google’s Test?

WordPress and Performance
One reason WordPress is so popular and so powerful is because it is incredibly modular and flexible. The ability to use plugins means functionality is limited solely to the imagination of plugin developers. Unfortunately, there is a price to this flexibility and power, namely that each plugin will have its own CSS and JS file(s), filters and other hooks which have a negative impact on front-end performance.

If you read articles on the topic, you will not find many people who have actually managed to get a perfect PageSpeed score and some even claim it is impossible. Well, it is possible and I have done it now with three sites (though the third site—this one—often drops a point or two because it is hosted on an inexpensive shared server which often has a slow response time). Of course, you should be skeptical of my claims, so here are a few screenshots as way of proof.

My Dado Que website:

Google PageSpeed Insights Perfect Score - mobile
Google PageSpeed Insights Perfect Score - mobile

My MBA Boost website:

Google PageSpeed Insights Perfect Score - mobile
Google PageSpeed Insights Perfect Score - desktop

This Lengthy Travel website:

Google PageSpeed Insights Score - mobile
Google PageSpeed Insights Score - desktop

One thing I will admit up front is that my perfect scores are for pages with no AdSense advertising on them. That’s right, if you use Google’s ad platform to earn money you cannot at the same time earn a perfect score from Google’s PageSpeed test (ironic, isn’t it?). You can still get a very high score (say 98 or possibly 99) but as of now I have found absolutely no way to get a perfect score with AdSense active. Later I will explain why.

Also note that I achieved the perfect scores without any special server setup or technical wizardry. There are WordPress-optimized hosting companies but I am not using one. Instead, this site is hosted on a cheap Hostgator shared server and the other two sites are hosted on a basic—no SSD or server-side, memory-based caching—ServInt VPS, which I have been using for many years

I also haven’t skipped much functionality just to achieve a good score. In fact, I use almost 50 plugins! See below for more about using plugins, but my biggest recommendation is that you choose your social sharing plugin very carefully since these can be particularly important to your site speed and performance scores.

A Content Delivery Network can be very helpful and I use a free one on this site but I use no CDN on the other two sites. Speaking of free, all of the optimization changes I have made are completely free.

One of my sites uses HTTPS and the other two do not.

Finally, lest you think I started with a high score and didn’t have far to go, that is not true. My initial PageSpeed scores ranged from 58-59 for mobile and 54-74 for desktop.

The Effect of Plugins
I use almost 50 different plugins on my site! That may seem a lot and perhaps I could get by with less, but what impact does having this many plugins actually have? While many will admonish against using too many plugins, they are not per se bad. Where they can cause problems is when they are: (1) poorly coded, (2) reference external scripts (CSS, JS), and (3) make extensive DB requests.

If you would like to get a better understanding of how the particular plugins you use affect your site’s load time, check out the very useful Plugin Performance Profiler (P3) plugin.

Of course, it is always a good idea when choosing plugins to ask yourself if you really need the functionality it provides and what impact it might possibly have on your site performance. If you add a new plugin after optimizing your site, be sure to re-run your performance tests to see what impact, if any, it had.

There are also ways you can modify your theme’s functions file to remove any negative effect a plugin might have on of your site’s performance. I will illustrate a few of these later but you may also want to read the useful article, “How WordPress Plugins Affect Your Site’s Load Time.”

Note: If a plugin adds design elements to your page, make sure it is responsive for mobile screens since it makes no sense to have a responsive theme that includes non-responsive content added by a plugin.

Beware What Your Read Online

This is probably not the first article on the topic you have read (though I hope it will be the last you need to). While I think reading experiences and tips from others is almost always a good thing, I also advise you to be wary of what your read. Here’s why.

First, each site is unique so it is quite hard to get an apples to apples comparison or prescription. Think a plugin sounds great? It’s almost guaranteed that you will find people who rave about it and people who claim it killed their site.

Second, many articles fail to give sufficient details about how and what they tested. Take load time as an example. Which test was used and what were the geographies involved (i.e., where are the host server and the testing server located)? Was the time listed an averaged time or a single (best) measure? What plugins or other tools were used? What day of the week and what time of the day? Which page was tested and what content was included or excluded? If a plugin was used, what were the settings? There aren’t right or wrong answers to these questions, but without knowing them you are not getting a complete picture and it is difficult to compare to the specific situation you are facing or replicate the suggestions offered.

Third, what results are you being shown? I recently read a well-written account of someone’s effort to get a high PageSpeed score, but only the desktop result was shown. In the comments someone asked about it and it seems that the mobile score was actually quite poor, so only a desktop optimization had been accomplished.

Finally, what tools and techniques were tested? There are many to choose from and it is almost impossible to test them all. It is unwise to say a plugin is the best solution if you haven’t compared it to alternatives, yet many folks do exactly that.

None of the above is meant to imply that reading other articles about optimization is bad. You can definitely learn a lot from them (I did) and, while every tool may not be tested and compared, after enough reading you will get a good idea of which tools seem worth testing.

Testing Tools

“Certain people fall prey to the idea that pages with HIGH Page Speed scores should be faster than pages with LOW scores. There are probably various causes to this misconception, from the name—to how certain individuals or companies sell products or services.” – Catchpoint Systems

Besides knowing which optimization tools to test (more on that shortly), we need to know which tests to use. So far I have only mentioned Google’s test, and it may be the main reason you are reading this, but I will discuss several others as well since getting a high score from Google does not necessarily mean you have truly optimized your site speed. In fact, there are some real weaknesses to relying only on Google’s test. Most notably, the results don’t actually tell you what your site’s load time is. The test also does not consider the use of a CDN or certain other performance enhancing tools and services.

Still, PageSpeed Insights is a test that cannot be ignored and its results can be an eye opener and generally offer a great starting point if you are just beginning to optimize your site. It is also the only test I am aware of that addresses mobile and desktop performance separately and which provides a mobile usability score and tips as well. This is especially useful because with today’s responsive WordPress themes, functionality and usability are often different for the two and therefor so is—potentially—performance.

Different Types of Tests

When we talk about testing our WordPress site, four main types of tests are involved.

First, speed benchmarking services test the actual speed or loading time of your site, sometimes from a geography you can specify and sometimes averaged over various attempts and distances. Because of these differences, results will often vary—sometimes significantly—when using multiple tests.

The second type of test provides a grade score (either numeric or alphabetical). These tests generally measure the quality and/or efficiency of the design and coding of your site. This is important because there is a correlation between that score and the actual speed of your site. Still, having a better grade than another site does not guarantee that your site is actually faster and the discrepancy can often be quite large. So, while grading tools are useful for giving you an idea of what you can do to get lower loading times, by themselves they are rarely sufficient to tell you about actual speed performance. PageSpeed Insights and feedthebot’s Pagespeed Optimization both fall into this category of tests.

Of course, some tests cover speed and performance. The three most popular are Pingdom Website Speed Test, WebPagetest, and GT Metrix (which also includes Yahoo’s YSlow test). The three are fairly similar but each has its own distinctions which make it worth using in addition to Google’s test. Helpful features to look for include: number of requests and page size; archived results (so you can go back and look at older results as a baseline); a waterfall showing how long each individual request on the page took; a display of file sizes, load times and other details about every element of a page; the ability to assess the performance of your website from different locations in the world; resource diagrams; a breakdown of your CSS and JS usage (inline vs. external, size); and a measure of how your site compares with the countless others previously tested.

The third type of test—a load test—attempts to evaluate how your site will respond under heavy use. This is typically done by having one or more computers in one or more locations emulate multiple users trying to use your site over pre-defined periods of time. For these tests, the quality and nature of your hosting provider will often be more important than your specific WordPress site configuration. Load testing services are usually not free. They are important but, unfortunately, beyond the scope of this article. Still, if you are interested in using them, some popular ones to consider are blitz.io, loader.io, Loadstorm, Siege and ApacheBench (ab).

Finally, there are specialty tests that focus on specific elements that affect performance and there are tools you can use from your local computer. Some of these include:

  • MaxCDN’s Ping Test lets you compare the ping speed of two websites in 5 seconds.
  • GIDZipTest lets you check if you have gzip compression working.
  • The REDbot tool checks the proper functioning of compression (gzip) and the browser cache.
  • feedthebot’s JavaScript usage tool lets you examine how JavaScript is used on a page while its CSS delivery tool will give you an overview of how your page uses CSS.
  • Webwait is a test you run from your own browser to time how long it takes to load a page. Because WebWait pulls down the entire website into your browser, it takes into account Ajax/JavaScript processing and image loading which other tools ignore. It loads a page over and over and then presents you with the average or median results. Thus, everything in your own setup can affect the time.

Regardless of which test(s) you decide to use, you should consider any results as a bit fuzzy. What I mean is that you can run certain tests several times and get slightly different results. This can be related to how busy your server was when the test ran, something specific to the testing server, etc. Don’t worry about it too much. The key is to look for large changes and the appearance or disappearance of specific warnings. Just run each test multiple times if you suspect something strange has happened.

Discrepancy between Speed and Performance

Earlier I mentioned that it is quite possible to have a high performance score and slow site speed and vice versa. This is especially noticeable if you employ a caching solution but don’t take any other steps to improve the performance items generally tested for. Alternatively, you could have a well-optimized site but one with large page size and/or poor server performance. The tools mentioned above that test both speed and performance are useful for seeing this discrepancy if it exists.

Testing Tips

When possible, I recommend you try both geographically close and distant test locations to see the load time differences for your site. You should also test more than once because multiple tests can show different loading time results. You also might want to try testing at a different time as perhaps the fluctuation is due to server load.

Mobile Responsiveness and User Experience

PageSpeed Insights actually shows a mobile user experience score as well as the speed score and offers some useful suggestions for making improvements. I am not sure to what extent, if any, a poor user experience score can impact your speed score, but in any case you should review the results and make recommended improvements that you consider appropriate for your site.

Understanding Speed Factors

Before getting started with actual optimization work it is perhaps good to understand at a high level what factors can actually affect site speed. The list of factors that come into play is long and this probably leaves off a lot, but here are some things to consider:

  • Type of server: WordPress optimized, dedicated, VPS, shared, cloud, SSD or disk storage, amount of RAM, etc.
  • Type of server OS (linux vs. windows; Nginx vs. Apache vs. LiteSpeed)
  • Ability to use Memcached, Varnish or similar server-based caching and acceleration tools
  • Plugin-based caching
  • HTTP vs. HTTPS
  • Nature of your permalink structure (flat vs deeply nested)
  • Amount of dynamic content and/or database (DB) queries required by your site (a function of the theme and plugins you use as well as WordPress itself)
  • Number of images, their size and whether they have been optimized or not
  • The use of video, Flash or other rich media
  • Overall size of your pages
  • Different types of pages (your score will vary from page to page for various reasons, including the fact that certain pages use plugins that aren’t used on other pages, some pages are more image heavy, etc. One big gotcha to beware of involves pages—like e-commerce pages—that you exclude from caching).
  • How many external scripts your site relies on and how, when and where these scripts are referenced in your page code (again, mostly related to theme and plugins)
  • Using (or not) a content delivery network (CDN)
  • Theme issues (layout, quality of coding, etc.)
  • DNS configuration
  • Use of redirects (usually 301, which are legitimate and should not be eliminated without good reason, but can slow down your site)

How Your Theme Affects Performance
The theme you choose may or may not have a big impact on your site performance. If it is a well written theme (uses few or no external scripts, uses only optimized images, minimizes database queries, etc.) you should have no real problems, but even an average theme may have less effect than some of the factors discussed above. Still, if you are looking for a new theme, why not choose a faster one? Raelene Wilson at WPMU Dev has put together a list of the top 10 fastest WordPress themes. For reference, I am using the Happenstance premium theme.

A Methodology for Testing Optimization Plugins

Site optimization is a real challenge and there is no magic formula. The nature of your “solution” will depend on the speed factors identified above, the different tools and services you choose to use and whether or not you can do some light or heavy lifting (via custom coding) yourself. You goals will also play an important role. Are you looking for a simple solution (say, via one of two plugins) or are you comfortable mixing and matching tools? What score are you willing to accept?

Obviously, since I have managed to get perfect 100 scores that means I have found a great combination of manual tweaks and plugins and I will share those with you soon. But, here’s the thing. Your site is completely different than mine or anyone else’s. So, your challenges will be different as well. And, frankly, there are a lot of tools to choose from. The fact that I am not using a tool means fairly little—it might be a perfect solution for your site. Because of this, the best strategy is to develop a structured method for trying and comparing different tools. My recommended methodology is to first test available plugins and then make manual changes. Here is the process broken down into steps.

Step 0: Backup Your Site and Use a Development Platform

Before starting, make sure your site is exactly the way you want it. That means every plugin, every theme design tweak, every external service, has already been configured and deployed. Any change you make to your site can and will affect your optimization results, so there is no point in testing before you are really ready.

Some of the plugins and changes you are going to investigate have the potential to really screw up your site. Having a backup that can restore your site to its original, working state is a must. There are a lot of good backup plugins but my favorite is UpdraftPlus Backup and Restoration.

While having a backup you can restore from is a must, the safest way to experiment with your site is to have a development version, though this does requires a bit of effort and, if you install one on your personal computer you won’t be able to perform any online tests with it because the tests need a working URL. See my guide for setting up a development version of your WordPress site if you are interested.

Step 1: Create a Child Theme

The very first thing you should do—if you haven’t already—is create and activate a child theme. This might sound intimidating but it really is quite easy to do and if you plan to make any manual changes is absolutely necessary because every theme update will destroy any previous changes made. I won’t go into details about this topic, but fortunately you can find everything you need to know via the official WordPress tutorial on how to create a child theme.

Step 2: Backup Again

If anything goes wrong with your child theme you can revert to your previous backup. Assuming everything goes smoothly, make another backup so you don’t have to repeat Step 1 if you need to restore a backup again later in the testing process.

Step 3: Decide Which Tests to Use

Choose the tests I identified earlier which you are interested in using. Personally, I used PageSpeed Insights, Pingdom, PageSpeedtest and GTmetrix.

Step 4: Create a Spreadsheet to Track Your Work

If you are comfortable with spreadsheets, create one that tracks the tests you have chosen and the tools you will choose shortly. In one column list all the tools you will try (include the base case you will run in the next step). Since many tools have multiple options, you may want to consider listing different tests with different settings. Just add a new row for each. In the top row, list the scores and the possible warnings you can get from the testing tool.

As you test, use the spreadsheet’s notes feature to make any relevant comments about a plugin. For example, WP Minify Fix is the only tool I have found thus far that can actually minify and cache external third party scripts like those from Google. It is easy to forget things in the midst of so much testing, so notes are useful.

To make things easier, feel free to use this public Google spreadsheet I created based on my own testing.
WordPress optimization results

Step 5: Get a Baseline Measure

Before choosing any tools to test or making any changes to your new child theme, test your site so you can track improvement and see what problems need to be addressed. Add the results to your spreadsheet on the first row.

Step 6: Enable Compression and Leverage Browser Caching

Two warnings you will most likely see in your base case test are “Enable compression” and “Leverage browser caching.” Some plugins can fix these errors, but you can also fix them easily by manually updating your .htaccess file. Simply add the following lines to the top:

Fixing just these two warnings will make a fairly significant improvement to your speed and performance results. Thus, the plugins that do this for you will probably seem much better than others. For this reason, I prefer the manual fix and then I consider the new scores the base case. I think this gives me a better feeling for how much improvement the different plugins I try are making.

Step 7: Choose Your Tools

Now it is time to add some plugins and other tweaks. If you have been doing a bit of research you may already have a list of things you want to try. If not, I will list some below, but in either case you will probably want to consider solutions based on functionality. But exactly what functionality is required? Here you may want to jump ahead to the section breaking down the individual things PageSpeed Insights tests to get a better understanding. The short answer is that we typically will want to consider doing the following things:

  • Leverage compression and browser caching
    Compression means that the code for a page is compressed by the server and de-compressed by your browser. Since sending less data over the Internet is faster, the page should load more quickly. Browser caching means that your page tells the visiting browser to keep a local copy of certain resources (especially images and external JavaScript and CSS files). If that user re-visits your page or visits another page of yours that uses those same resources, they will be loaded by the local computer rather than downloaded from your server, thus speeding things up nicely.

  • Move external resources (JavaScript and/or CSS files) to the end of the page
    This allows a page to load more quickly by not having to first wait for an external file to load.

  • Defer or load external files asynchronously
    This has more or less the same goal as moving things to the end of the page.

  • Combine multiple external files
    This reduces the need to load multiple files before rendering a page, thus increasing speed.

  • Inline CSS and JavaScript where appropriate
    Having code inline is faster than loading it from external files and can help a page avoid render blocking, but it is a tricky thing with possible drawbacks.

  • Minify HTML, JavaScript, and CSS
    Page code usually has a lot of extra whitespace and other space inefficiencies that certain tools can eliminate.

  • Caching
    Normally a WordPress page is built by assembling various pieces of the page (content, the theme design, external resources and images, plugin-specific functions, etc.), which requires multiple calls to the database. By caching these dynamically generated pages, visitors see plain HTML pages instead, which significantly lowers the loading time and the stress on your server. This single tool will often have more impact than any other.

    There are many caching plugins to choose from. Some are extremely simple and some quite complicated. Some offer extra features, such as minification and pre-caching pages. Some—including WP Super Cache, W3 Total Cache, and WP Rocket—support Content Delivery Networks and some—including Hyper Cache, Quick Cache, and WP Fastest Cache —don’t. Finally, some conflict with—or require special configuration to play nice with—popular plugins, especially membership and e-commerce solutions.

    Whichever caching plugin you test, if you make changes to your site while using it you will have to clear the cache in order to see the changes. For this reason, I recommend testing caching plugins last.

  • Content Delivery Network (CDN)
    A CDN is a network of servers around the world which cache a copy of the static parts of your site and serve these to your site’s visitors from the server closest to their location, thus speeding up page loading time. Most CDNs—like the popular MaxCDN and Amazon CloudFront—are paid products, but CloudFlare offers a good free plan.

    Some caching plugins only play nice with certain CDNs and some might not play nice with any. Be sure to read the documentation for both plugin and CDN.

    If your cache plugin and your CDN both offer extra features, like minification, make sure to only use one. As with my advice for caching, I recommend you test a CDN last.

    Be aware that some tests—notably WebPagetest and GTmetric/YSlow—account for the use of a CDN and some—notably Google’s PageSpeed Insights—don’t. Interestingly, a CDN can potentially make your site marginally slower on a “local” level but make it much faster when tested around the world.

Techniques to implement the functions just listed can usually be made via a plugin and/or by modifying your theme. To get started, here are some of the plugins I have read good things about and given a try myself:

  1. a3 Lazy Load
  2. Async JS and CSS
  3. Autoptimize
  4. Better WordPress Minify
  5. Cloudflare (plugin)
  6. Falcon Engine (Wordfence)
  7. Hyper Cache (+ Autoptimize)
  8. Speed Booster Pack
  9. Use Google Libraries
  10. W3 Total Cache (W3TC)
  11. WP Fastest Caching [Freemium]
  12. WP Minify Fix
  13. Zen Cache (formerly Quick Cache) (+ Autoptimize) [Freemium]

Other plugins worth considering that I didn’t personally test include Minit, WP-Rocket, WP Super Cache, and WP-cache.com.

This list is far from complete and I may be missing some great tools because I am unaware of them. If you know of a great tool I have ignored, please share in the comments.

You can rely on this list to get started but you probably should search the official WordPress plugin directory for even more options. Later I will discuss manual tweaks (with code) that I made.

A Note about W3 Total Cache
I am a fan of W3 Total Cache. I even wrote an article about using W3TC to speed up your website (though I think Baruch Youssin has written a better tutorial). But, that was before I decided to really learn more about WordPress. After doing so, I decided to challenge my assumption that W3TC was the best tool for the job. In my particular circumstances I realized it is not, but I still think it is a great tool and I encourage you to include it as one of the options you test for yourself.

Step 8: Organize and Prioritize Your Tests

The order you test your selected tools is not too important, but as I mentioned earlier I recommend testing non-caching options first because when you use a caching plugin you need to clear the cache anytime you make a change you wish to test.

I would prioritize simpler plugins first. If a plugin does only one thing and has few options, it will be easier to test and will give you a pretty immediate idea of its effectiveness. If you are going to test more complex plugins that contain the same functionality as a simpler plugin, consider testing just that functionality separately from all options combined.

You can test various plugins without fully understanding what they do, but the more you understand the better, especially because some options are fairly safe to use and some can cause major problems for your site. With this in mind, before you test any plugin, take time to understand its functions and options. Where appropriate, test different functions and combinations thereof separately. Be sure to enter every test you plan to run on its own row in your tracking spreadsheet, possibly including multiple rows covering various plugin options.

It will be tempting to jump ahead and start testing multiple plugins together. Be disciplined and avoid this temptation. After you have all your individual plugin results you can review them and see which combinations of tools might solve the most warnings possible. Track these combinations on separate rows of your spreadsheet. If you use my public template you will see I have used different colors for individual plugins and combinations.

Note that some plugins can work together and others cannot. You will have to figure this out for your situation but generally, two caching plugins won’t work together. Also, two plugins that can both alter JavaScript or CSS probably won’t work together unless you use one for JS and the other for CSS.

Step 9: Test and Track (with Tips and Warnings)

Now, run your tests and enter the results in your spreadsheet. As you run more tests, hopefully you will start to learn a lot more about your theme and the plugins you use and how they might be affecting your performance. You may even decide to drop or change some plugins. Likewise, you will start to better understand the performance factors that PageSpeed Insights considers and how important they are relative to each other (i.e., some have more score impact than others). You will probably also decide that combinations of plugins and options you hadn’t previously considered should be tested. Just test them and add the results to your spreadsheet as you do.

To be thorough, you should test multiple pages. A home page or blog index page will typically be different from a post. And posts with many images and videos will perform differently than basic posts. Likewise, custom pages, archive pages, etc. will all potentially perform differently and should be tested separately.

It may seem overkill to test multiple URLs separately, but it is the most accurate way of testing performance as different plugins handle different types of pages in different ways. Of course, being realistic, that is a lot of work. A compromise is to test one or two pages and later in the process as you narrow down your final tool choices go back and test more pages.

Speaking of being thorough, you should check to make sure a plugin doesn’t break your site. Like testing multiple pages, this can be a pain, so focus on one or two pages and then check more thoroughly later in the process after you narrow your plugin selection. When you do check, pay special attention to any features created by plugins. For example, if you use a ratings plugin or page view tracking plugin, those functions may be broken. Ad management plugins may or may not work properly, etc. Most servers create error logs (sometimes, conveniently, in the root and/or theme folder). Find out where yours is located and see if it has any errors listed.

Here are some other thing things to consider as you activate plugins and run your tests.

  • Google is really strict about their image optimization warnings. Even if you use a great plugin like EWWW Image Optimizer to optimize all your images, Google will probably not consider your efforts to be good enough! So, in your base case you will probably see an image optimization warning from the PageSpeed Insights test. Whether you want to fix these issues before continuing your tests or do so after is a personal decision. I opted for doing so later, but if I had to do it again I think I should have done so at the beginning.
  • A common responsive design technique is to change the navigation menu dynamically as the screen size changes. Usually this works just fine, but it is possible that some of the things you will do to try and optimize speed might break it so after making tweaks always resize your browser to make sure the responsive navigation and design is still working well.
  • If you have member-only content, make sure you test that separately. Take special care with any caching to make sure both non-member and member views are presented properly.

Testing and Tracking Manual Changes
Sometimes while testing a plugin you may learn something useful that leads you to implement a manual tweak. This tweak may be specific to that plugin but it also might be a change you want to make in all circumstances. In the latter case, to be thorough you should repeat the tests you have already made, this time including the new manual change. Whether you are that disciplined or not is a different matter.

Step 10: Choose Your Final Plugin(s)

After you finish your plugin testing you should hopefully have a combination of plugins and their respective configurations that perform best for your site. Activate this combination and remove all the plugins you decide not to use.

Step 11: Manual Tweaks (Tackling Google PageSpeed Insight’s Tests)

You now have your preferred combination of plugins but almost certainly you have not gotten your 100 score yet. The only option left to close the gap is to make some manual tweaks. If you are satisfied with where you are now, feel free to call it a day. If not, read on for a look at the specific tests PageSpeed Insights performs and recommended coding changes you can make to fix warnings given by them. I will provide the necessary code and instruction so I think anyone can implement these, but leave a comment if anything I discuss is not clear enough.

My Personal Solution

After all my testing, I was able to accomplish my goals with just two plugins: Speed Booster Pack and Wordfence’s Falcon Engine (especially good for me since I already use Wordfence as a security solution). Note that this combination lacks a minify solution. For this site I am using the minification tools Cloudflare offers. For my other sites, I decided to implement a manual minify solution, which I will detail later.

As I have tried to emphasize, your site is probably quite different than mine so you should run through the previous steps to find your own best tools, but I do recommend you include my combination in your tests.

Understanding WordPress: Tackling Google PageSpeed Insights with Code Changes

Most of the manual coding changes I have made involve working around issues with external scripts so I will first discuss at a high level how these are handled by WordPress using the concepts of enqueuing/dequeuing and action and filter hooks.

Script, File, Resource
When I (and others) talk about including code from a file other than the main HTML file loaded in your browser, I will often use the words script, file and resource interchangeably. A script should really only refer to a JavaScript file but common practice across the Web has it often used to refer to a CSS file as well. Likewise, an external resource is either kind of file.

Enqueuing

Enqueuing is one of the most important concepts to understand when you want to really master WordPress. I doubt that is your goal, but since it is something we need to use for many of our manual performance tweaks, let me try to explain it.

Every theme and plugin potentially can include two types of external resources, styles (CSS files) and JavaScripts. The core WordPress program has some as well (notably, jQuery). This system helps make WordPress very flexible and powerful but the problem is how to know what order to load all these external resources. In some cases, any order might do just fine, but often one resource relies on another being loaded before it. Another concern is making sure that the same resource isn’t loaded more than once (say, by two plugins that use the same JavaScript file; this is especially the case with jQuery since it is widely used).

In the old days—and, unfortunately, occasionally still today—developers would just write the code needed to include an external file directly in their plugin functions. When this is done, WordPress—and other plugin developers—have no control over the order or nature of loading that resource. You can imagine the trouble that would result if every theme and plugin developer did this.

As a solution, WordPress has declared that the proper way to load an external resource is by what they call enqueuing. Since the software is actually creating its own “queue” of external files, this is a logical word to use. To solve the problem of deciding where in this queue a script should be placed, WordPress allows the enqueue method to specify a dependency (telling WordPress what other script(s) need to be loaded first) and a priority (a default priority is 10 so if you set a priority to be higher or lower, your external resource will be loaded after or before any that are set with the default). Sometimes you can ignore both of these, but if your code requires that another resource is already loaded before you load one of your own, using one or both of these is a good way to do that.

The WordPress developers also created a way to dequeue resources. This is crucial because it lets you “fix” problems that might occur when a plugin you are using has enqueued a resource in a way that adversely affects your site’s performance. Simply dequeue the problem resource and re-enqueue it with proper dependency or priority. Later, we’ll also see that some plugins and themes enqueue scripts on every page even though they may not be used at all or may be used only on certain pages. This is obviously not optimal and, thanks to the dequeue method we can fix this inefficiency.

Register vs. Enqueue

Technically speaking, there are two steps to enqueuing: first you register a resource then you load it. I won’t go into details about this but just know that enqueuing actually takes care of both registering and loading. The difference exists because there are some cases where you might want to register (declare) an external resource but actually load it in a different place. That is beyond the scope of this guide so don’t worry about it.

Handles

The last important thing to know about enqueuing in WordPress is the idea of a handle. Basically, this is just a nickname a developer gives for the script. Whenever you enqueue a script you need to specify a handle and the exact location of that script. Why both? Mostly for convenience. As I just mentioned, you can register and load a file separately. If you have already registered a script, WordPress knows its location so when you are ready to load it you can just reference the handle. Likewise, if you want to dequeue and re-enqueue a script, knowing the handle is enough.

So, how do we find handles used for our site? There are various ways to do this. Probably the easiest is to use a plugin like Debug Bar List Script & Style Dependencies (requires the Debug Bar plugin) or Debug Objects. If you prefer a solution that doesn’t require a plugin, the following code—modified from code by the author of the Debug Objects plugin—in your child theme functions file will do the trick.

That will only list the handles (and file URLs) for a logged-in administrator (e.g., you) so the whole world won’t be seeing it. But, you still will want to remove or comment out this code once you have the information you need.

Finally, if you have a text editor that can search for text in multiple files (e.g., in a directory) like my favorite Notepad++, then just search for the filename you are concerned with. Somewhere you will see an enqueue command that will include the handle name.

Action and Filter Hooks

To really master WordPress, in addition to understanding enqueuing you also need to understand hooks. That is especially true since you cannot enqueue or dequeue a file without a hook. Again, I will just give the big picture.

According to the official WordPress site, hooks “are provided by WordPress to allow your plugin to ‘hook into’ the rest of WordPress; that is, to call functions in your plugin at specific times, and thereby set your plugin in motion.” There are two kinds of hooks:

  1. Actions
  2. Filters

Basically, an action lets you add or remove code whereas a filter lets you modify (replace) data. Sometimes either can be used, but depending on what you are trying to accomplish one is preferred (or required).

Whether you are adding or removing code via an action or replacing data via a filter, WordPress needs to know when to execute your code. That is what the hooks are for. WordPress builds a page in multiple steps and each of these steps is a hook. The steps that probably make the most sense to you would be to first load the header of the page, then the content, then any sidebars and finally the footer, but there are actually many more hooks that developers rely on.

Implementing actions and filters is accomplished via the add_action and add_filter commands. These commands use some parameters, most notably the actual hook to use, the name of the function you create and wish to run, and the priority. In the code I presented above for listing handles, the last line is:

This is an example of using the add_action command. Here I am omitting the priority parameter because it is optional and not needed for what I want to accomplish. But on the topic of priority, I should clarify that the hook you use to enqueue is its own sort of priority. A high priority on an early hook will be implemented before a low priority on a later hook. There are best practices for which hooks to use to enqueue scripts (usually the wp_enqueue_scripts, wp_print_scripts, and wp_print_styles hooks) and knowing which are used for the relevant scripts on your site will help you make any manual enqueuing changes.

Looking again at the line of code above, wp_print_footer_scripts is the hook. This particular hook comes toward the end of the page building process (i.e., a very late step), which is what we want because we don’t want to miss any external scripts that are loaded in the footer (for reference, wp_footer is the hook immediately prior to wp_print_footer_scripts).

Don’t Worry If You Are a Bit Confused

Enqueuing and action/filter hooks are not the easiest concepts to master so if you got a bit lost in the last sections, don’t worry too much. Below, I will show you actual code changes I made that might also be useful for your site. Along the way, hopefully these concepts will start to make more sense.

Removing Unused Scripts and Styles

Ideally, themes and plugins should never include JavaScript and CSS files for features and functions that don’t get used, but the reality is that many do. These may or may not cause any PageSpeed warnings, but to fully optimize your speed you should remove them. To do this, you will need to know the script handle(s). For example, my theme offers a tab widget (popular posts, latest comments, etc.) that I don’t use. This widget actually relies on both a CSS file and a JavaScript file so I need to dequeue both. As it turns out, the handles for both are called “theme_tab_widget.” Here is the code I use:

Let’s take a quick look at what is happening here, keeping in mind the earlier discussion of action and filter hooks.

The first parameter in the add_action line is the action hook (wp_enqueue_scripts) that most theme and plugin developers use to enqueue their scripts. The second parameter is the remove_assets function which we created in the lines above the add_action command. The final parameter is the priority number. The default priority number for WordPress is 10 so by using a number higher than that we will be running our function after all the default enqueuing has been done. That, of course, assumes that developers used the default. Some might set their own high value (say 20 or 99). So, we use a really high number (99999) just to be safe.

Note that we use two different wp_dequeue commands. wp_dequeue_script will dequeue a JavaScript file and wp_dequeue_style will dequeue a CSS file. As I said, my theme’s tab widget uses both but often you will only be dealing with one or the other.

My theme ended up including four features (8 total files) that I don’t use. I have only illustrated the tab widget feature, but you can just replicate the dequeue commands for other unnecessary scripts.

Limiting Scripts and Styles to Certain Pages: Contact Form 7

Contact Form 7 is probably the most popular contact form for WordPress. If you are like me, you only use it on your actual contact page but it loads its script by default on every page, which is wasteful. So, like above, let’s dequeue it—but add some code to make sure it is not dequeued on the contact page. In the same remove_assets function, add the following lines:

So the function now looks like:

The key here is you need to change “contact” to the page slug for your contact page.

Dequeuing Tricky Scripts

One of my sites uses a pricing table plugin which was presenting me with two problems. First, like Contact Form 7, it loads a JavaScript file on all pages even though I only use the plugin on my home page. Second—and I really don’t know why—this plugin’s CSS stylesheet was causing a warning from Google PageSpeed Insights (of course, I should investigate more to find out).

Since the CSS involved is quite small, I decided to just dequeue it and manually add the CSS styling to my main child stylesheet. And, the solution to the first problem is basically the same as for the Contact Form 7 script. But, in the end I was unable to dequeue either file.

After banging my head a bit I found out why. Remember my discussion of action hooks and how they form their own sort of priority? And, remember I said that the wp_enqueue_scripts action hook is the one most theme and plugin developers use to enqueue their scripts? Well, apparently the developer of this plugin enqueued the files in an action hook which occurs after wp_enqueue_scripts. The end result is that I couldn’t just include dequeue statements in my previous remove_assets function. Instead I needed a new function that was called via a later action hook, as follows:

This looks a lot like the previous code but I have replaced wp_enqueue_scripts with wp_print_footer_scripts.

If you run into similar problems try this action hook or, more generally, look at the official WordPress list of action hooks. The first section, “Actions Run During a Typical Request” lists in order the action hooks. The most common action hooks I see referenced in online discussions are (in order of precedence):

setup_theme
after_setup_theme
init (Typically used by plugins to initialize. The current user is already authenticated by this time.)
wp_enqueue_scripts
wp_print_styles
wp_print_scripts
wp_print_footer_scripts

Localize External Scripts: Google Fonts

My theme, like so many these days, uses a Google font for its default and allows the user to choose from many others. The problem with this is that the font is loaded from the Google servers, which causes PageSpeed warnings. Since a font is not something likely to change often (if ever), a good solution is to make a local copy and include it directly in our stylesheet. Here’s how to do that.

First, as with our unnecessary scripts (e.g., tab widget) above, we need to dequeue the external reference. In the remove_assets function from before, add the following line:

replacing theme-google-font-default with whatever handle your theme is using for its Google font. Now our code looks like:

Creating a local copy is a bit more complicated, but not so bad. First, you need to visit the Google URL called by your theme. For example, my theme uses the Oswald font and it is loaded from:

https://fonts.googleapis.com/css?family=Oswald&subset=latin,latin-ext

If you visit that site you will see the following:

We want to add this code to our child theme stylesheet, BUT first notice that two different .woff files are referenced in that code. Since these are also on external servers we will get warnings for them if we just leave the code as is. So, simply visit each of these URLs and download the respective files to your child theme folder. I put mine in a folder I call “fonts”.

Now, edit the above code to be like this:

That’s it. Of course, if you put them in the main folder or a folder called something other than “fonts” you will need to change that part of the above code.

Localize External Scripts: Font Awesome

Font Awesome is an increasingly popular tool for theme designers. The problem is that it is usually referenced from the original external source and thus will produce a warning like our Google font did.

The solution is to load this from your child theme like we did with Google Font. But, Font Awesome is slightly more complicated than a single Google Font so you will actually need to download the font as a .zip file at:

https://fortawesome.github.io/Font-Awesome/

Simply unzip it to your child theme (I put it in my assets/fonts/ directory) and then enqueue it as follows:

Of course, as with our Google font, we first need to dequeue and deregister the previously enqueued instance. But, here is where it gets interesting. Remember I just said it is an increasingly popular tool? Well, that means it might actually get loaded by your theme as well as one or more plugins you are using! In my case, three plugins enqueue Font Awesome. Two use the ‘font-awesome’ handle so if I just dequeued that handle I would have been fine. A third plugin (Simple Share Buttons Adder), however, enqueues it with a handle called ‘ssbp-font-awesome’ so I had to dequeue that one separately. Here is what my code looks like:

Localize External Scripts: Minified JavaScript Files

A couple of JavaScript files—one from my theme and one from a plugin—are not minified. Although it sounds a bit odd, my solution is localize these local scripts; that is, make a minified copy in my child theme (in my assets/js/ directory). I could just minify the originals but any update of the theme or plugin would replace the files. Again, I use the remove_assets function.

So, now my function looks like:

Localize External Scripts: Not All Files Are Equal

When localizing external files there are two types we need to treat differently: files that are unlikely to change (like my examples above) and those that might change regularly. In both cases we make a copy of the external file and store and retrieve it from our child theme but in the latter case we will need code to regularly update the file. At the moment, Google Analytics is the only such external file that I think is worth localizing and Jørgen Nicolaisen has written a useful guide for doing just that (Matthew Horne offers a similar approach with slightly different code). With a little imagination, you can easily modify his code to work for other external scripts as well, and keep them all updated via just one cron job.

Breaking Down PageSpeed Insights Tests

Now let’s turn our attention to code modifications you can make to bump up your score hopefully toward the 100 mark. To do so, let’s take a look at what Google actually cares about in its tests and discuss ways to pass each of them.

Landing Page Redirects

This is not something I had to worry about at all and I guess you won’t either. If you do, check out Google’s documentation on redirects. Mostly, it talks about sites that redirect mobile devices to a special m.domain.com URL, but these days responsive designs are becoming the norm and such redirects are no longer necessary. I suppose if you had an old site that was redesigned and you implemented a lot of 301 redirects (which is exactly what you should have done) then you may see this, but honestly I don’t know what actually triggers a warning for the test.

Enable Compression

We already discussed this issue and you should have added it via your .htaccess file (or possibly via one of the plugins you selected). Therefore, at this point you should be passing this test.

Server Performance (Reduce Server Response Time)

Google prefers to see a site hosted on a snappy server. The rule at present is that your server should have a response time of 200ms or less. A lot of factors can affect your server’s response time. Most of these are determined by your hosting company and type of server. It should be clear that a cheap, shared hosting plan is going to perform more slowly than a VPS or dedicated server. But, the nature of operating system and configuration of the server itself are also important considerations. And, things aren’t completely out of your control. By optimizing your site—as we are doing here—and especially by using a caching solution, you can decrease the response time.

Take this site as an example. Before my optimization efforts I was seeing server response times of about 1.4-1.7s. This is not very good. After implementing all my changes I have it down to 230-270ms. That is a big improvement, but still not good enough for Google and I get hit with 1-2 points as a result (though sometimes it does get below 200ms and I get the perfect score). At the end of the day, if after all your hard work you cannot get below 200ms you will either have to accept the speed score penalty or try a different hosting setup.

If you decide that you want to change your current hosting provider or setup, you might want to consider one of the increasing number of WordPress optimized providers, though be aware that most charge a premium compared to traditional shared hosting. Whether this premium or end product is worth it is an open question. I haven’t yet found a good comparison between the two different types of hosting options, but if you are committed to a WordPress optimized host, Kevin Ohashi’s article, “Managed WordPress Hosting Showdown – Performance Benchmarks Comparison” (and part 2 with even more hosts covered) is a good read. [Note: the final list of Top Tier WordPress Hosting Performance providers was A Small Orange, GoDaddy, Kinsta, LightningBase, MediaTemple, Pagely, Pantheon, and WebSynthesis.]

For more information, “Server response time” by Patrick Sexton gives a very good big picture look at what affects server response time and some things you can do to improve yours.

Prioritize Visible Content

How a Browser Loads a Webpage
“When your webpage loads, the browser takes certain steps that determine how the page will load (this is a simplified version, but basically what happens):

  • Browser downloads HTML file
  • It parses (looks through) the HTML
  • It encounters something it must load (image, external CSS file, etc.) and stops parsing HTML
  • It loads the external resource
  • If external resource is CSS or JavaScript it then parses that file
  • It then continues to parse the HTML until it comes to another resource that must be loaded
  • Throughout this process, the browser is trying to show as much of the content as possible, as soon as possible. There are therefore ways to ensure some of our webpage content loads first and completely, before the browser encounters hurdles like external resources.
  • Above the fold content can be prioritized by not making it rely on any external resources, or loading those resources early, before the browser has to load anything that must be parsed.”

– Patrick Sexton, “Prioritize visible content

According to Google, “this rule triggers when PageSpeed Insights detects that additional network round trips are required to render the above the fold content of the page.” What that really means is that all the code necessary to actually load a page should be included and “rendered” before having to download external resources.

Usually, external files loaded by plugins and/or your theme trigger this warning. A lot of plugins are used on widgets that get placed on the sidebar (e.g., advertisements, social follow buttons, a list of popular or recent posts and comments, and a live Twitter feed). But, why should a user have to download all of this before they can see your page? Fortunately, if you are using a well-designed theme, the sidebar will be loaded after the header and main content so it shouldn’t trigger a warning. If you aren’t, you might consider a new theme.

Another common trigger for this warning is the placement of ads from an external network like AdSense above the fold. If this is the case, you will have to decide which is more important, the possible revenue generated by the ads, or a couple points higher score.

One other common trigger for this warning is your responsive navigation menu. This is usually achieved via JavaScript, which—as we will see shortly—can cause render blocking warnings. The solution to those warnings is typically to load the JS file asynchronously and/or at the very end of the page. The problem with this solution is that the navigation menu is above-the-fold content.

So, what can you do? Of course, it depends on the type of responsive menu your theme is using. One option is to search for a responsive menu plugin that won’t give you either a render blocking or prioritize visible content warning. I don’t know if such a plugin actually exists because I wanted to use my theme’s responsive menu.

Since my theme’s responsive navigation menu uses a fairly small amount of JavaScript I decided the best solution is to place that code inline at the end of my pages. I did this by opening the two relevant JavaScript files loaded by my theme and combining them. Then I used an online JavaScript compression tool to optimize the combined code. Finally, I took that minified code (just three lines) and added it to the bottom of my footer.php file in my child theme right before the </body> tag. Problem solved!

Leverage Browser Caching (a.k.a “Damn You Google!”)

There are two types of caching. Server caching is usually done via specialized server software or by a plugin. Hopefully, you have your server caching solution figured out already. Browser caching is what it sounds like; several website components—images, CSS, and JavaScript—are loaded only once and then are stored in the browser (local computer) cache. The next time one of those components is needed it will be pulled from the user’s computer rather than downloaded from the server, thus greatly improving load speed.

Leveraging browser caching is usually a good idea with little downside, but do keep in mind that if you change a component that is being cached, the user will not see the new component until the cache expires. For this reason, you should set cache expiration times according to how frequently you plan to change a component. For most blogs, changes are infrequent so a long expiration time is appropriate.

I provided the code to enable browser caching together with the code to enable compression so you should have already modified the .htaccess file. Unlike compression, however, there is a good chance you are still getting warnings for this test. And there is a good chance that Google Analytics and Google AdSense are partly (or solely) to blame. You might naturally wonder why.

The simple reason has to do with what I just said about setting expiration times for resources. What I didn’t mention is that these expiration times are set by the server that actually hosts the file(s) being downloaded. Since most scripts required to load your site are located on your server, you are in control of those and the changes we made to the .htaccess file will prevent any warnings. But, Google’s scripts are downloaded directly from Google servers and those servers set the browser caching. For whatever reasons, Google has determined the amount of time before the cache should expire for these scripts should be fairly short—short enough, in fact, to trigger a warning on its own test.

So, what can we do to rid ourselves of these warnings? The short answer for Google AdSense is not much. For most other culprits, we can use a local copy of the required files instead of downloading them from the original server. I discussed this already and it can be a bit complicated (though definitely doable) so it is probably not worth the effort for the 1-2 points Google will deduct from your score. Still, if you are intent on scoring that 100, give it a try.

A Reverse Proxy Solution?
The always-useful site Stack Overflow has addressed the browser caching issue multiple times. In one entry a user suggests using Apache to reverse proxy the external resource. I really don’t know much about this idea and haven’t tried it at all so I don’t know how useful it may or may not be.

Google Analytics and AdSense aren’t the only culprits to be concerned about; another is your commenting system’s use of gravatars (Globally Recognizable Avatar). The good thing about gravatars is that they seem to be well-optimized so you won’t get image optimization warnings. The bad thing is that the browser caching for gravatars is set to only 5 minutes which gets the Google warning dogs barking.

Localizing gravatars is a slightly different animal than localizing an external JavaScript. You can easily download the actual gravatar to your server and don’t need to worry about regularly updating it since it is just an image. What is a bit tricky is getting WordPress to actually use your local copy. I did this—as usual—with a little code in my functions file, which I found here:

Note that I have named my local gravatar profilepic.jpg and placed it in the assets folder of my child theme. Since I am the admin of the site my user ID is 1 but if yours is something different you should change the code above accordingly.

Next, you can choose to localize the default comment avatar (shown for commenters that don’t have a gravatar). To do so, add the following code—which I modified slightly from App Shah’s useful article—to your functions file:

Change 'URL OF YOUR CUSTOM AVATAR' as appropriate. If you are using a child theme with a file called defaultavatar.jpg in a folder called assets, your code would look like this:

Now, from the WP admin panel, go to Settings -> Discussion -> Default Avatar. You will notice a new option called Localized Avatar has been created at the bottom of the lust. Select this and save your settings.

So, that takes care of your personal gravatar and the default avatar but what about guest gravatars. Well, the short answer is I don’t think there is a good way to localize those. I suppose you could choose not to show avatars at all or replace all user gravatars with a new default image but I think that is straying into the territory of valuing some meaningless metric (PageSpeed score) over site usability. People take the time to comment and showing a dull default image instead of their personalized avatar is a bit rude. I say be grateful that people comment on your posts and accept the very small page speed hit that results.

A final tool I came across that will trigger the browser cache warning is the “Page content protection” feature found in the Scrape Shield plugin with Cloudflare. This is not enabled by default so you probably won’t notice it but if you do enable the feature Cloudflare will add a small image to your pages (that’s how it detects stolen content across the Web) which will trigger the warning. This is unfortunate because it is a nice free service. Ultimately, you have to make a decision – trade a small hit to your score for a potentially very useful feature?

Render Blocking (Optimize CSS Delivery | Remove render-blocking JavaScript | Use asynchronous scripts)

Render blocking is probably the Google warning that most exasperates us when trying to improve our score. I have already talked a bit about how a page gets loaded in the section on prioritizing visible content so you know that loading an external CSS or JS file “blocks” the rendering of a page until the download is complete.

The basic ways to solve render blocking issues are:

  1. Load JavaScripts at the end of a page. The main reason to do this is that scripts are fetched and executed immediately when the browser encounters them and thus the HTML page cannot finish rendering until the script has been executed. Any delays in downloading or any errors in the script will cause more delay. Moving these scripts to the end of a page will improve site speed considerably. The problem with doing this is that some site functionality requires certain scripts to be loaded before working. For this reason, Patrick Sexton recommends that you separate your JavaScript into two groups: JavaScript the page needs to load (jQuery is a common one) and JavaScript that is doing stuff after the page loads. Patrick’s JavasSript usage tool can help you with this task. Fortunately, some optimization plugins—like Speed Booster Pack—give you the option to specify which scripts should not be moved to the bottom of the page.

    You can also load CSS files at the end of a page, but this will often cause the user to start seeing the page content without any styles because the rules from the external stylesheet haven’t been loaded and processed yet. This situation is called flash of unstyled content (FOUC).

  2. Defer load JavaScripts or load them asynchronously. What’s the difference between loading a script asynchronously (async) and defer loading it? It’s a bit complicated, but there are two key differences: (1) Older browsers don’t support async and (2) Each async script executes at the first opportunity after it is finished downloading which makes it likely that async loaded scripts will not be executed in the order in which they occur in the page. Deferred scripts, in contrast, are guaranteed to be executed in the order they occur in the page but only after parsing is completely finished. If you use either of these techniques, it shouldn’t really matter where you put the code (in the header or the footer) but the same warning applies—page elements that require JavaScript won’t function (and possibly display) until after the script is loaded and executed.

  3. Combine external scripts. Some optimization plugins let you combine multiple JavaScript—or, alternatively, CSS—files into one. This is useful because it is always less efficient to load multiple files. This combined file will still trigger a render blocking warning unless you move it to the footer and/or load it asynchronously. Yet again, the downside of this technique is that your page may not load until this file has been fully read and executed. If you have separated your scripts as recommended earlier, you can combine the first group and load it (no async or defer) in the header and combine the second group and load it in the footer asynchronously.

  4. Inline your external scripts. Inlining just means taking the code from an external file and adding it directly to your HTML. This will definitely eliminate render blocking warnings but is not actually recommended unless your scripts are fairly small in size. If not, you will have a large page to download and you won’t benefit from browser caching (we don’t browser cache HTML documents since they are frequently updated with new content). Again, if you have separated your JavaScripts as recommended in the previous technique, you may want to inline just the JavaScript needed to load your page, assuming it isn’t too large. Recall that is exactly what I did in the Prioritize Visible Content section with my responsive navigation menu.

Use Less CSS
“There are several reasons why there is so much unused CSS loaded on most websites.

  • WordPress themes that are customizable have massive additional CSS that is not required
  • Frameworks … are used, but the CSS is not tailored to the resulting website
  • In general, the amount of CSS was not worried about in the past, so designers make their jobs easier by using more CSS than is required

Whatever the reason your CSS is massive, you still need to figure out how to make it smaller and smarter. If you wrote the CSS or are the one in control of it, you can take the time to only include the CSS that is needed. It is more likely however that you have bought a theme or design from someone else, and in this case the only real solution is to speak with the designer who created the CSS and request a slimmer version. If you are considering a new design or theme, you can save yourself time and money by making optimized CSS delivery a requirement of the project.”
Patrick Sexton

Judicious and clever use of the above techniques should hopefully completely eliminate any render blocking (and prioritize visible content) warnings. If you are lucky, one plugin like Speed Booster Pack will do the job for you (though you might need to really learn how to use the tool properly first). If not, you will need to manually fix any problem scripts via the enqueuing technique discussed earlier.

I already mentioned that external Google scripts will cause a leverage browser cache warning. Since Google Analytics loads asynchronously it won’t cause a render blocking warning, but I opted to load a localized copy instead to prevent the browser cache warning. Google AdSense does not load asynchronously by default but you can easily change that by adding the “async” text in your ad management plugin, like follows:

You can easily localize the adsbygoogle.js file above as we did with Google Analytics (be sure to change the URL accordingly). That will eliminate the browser cache warning for that script. Unfortunately, somewhere in the AdSense JavaScript code, one or more of the following files get loaded: osd.js, expansion_embed.js, templates.js, and show_ads_impl.js. While these thankfully won’t trigger a render blocking warning they will trigger a browser caching warning. Perhaps there is way to localize these files as well, but you would need some JavaScript ninja skills and would almost certainly be in violation of Google’s terms and conditions. Thus, we now understand why you simply cannot get a perfect 100 score if you use Google AdSense.

Identifying Above-the-fold CSS
“There are automated tools that claim to do this; however, I have not found one that does the job correctly.

I installed two extensions to my Firefox browser: Firebug and CSS Usage. I logged out of my blog (to make sure that my site is displayed without the admin bar), opened my page in Firefox, right-clicked on the page and selected Inspect Element with Firebug. In the Firebug window I selected the rightmost tab, CSS Usage. I pressed Scan and got a detailed report on my CSS. I went over all selectors looking for green-colored ones that are applied, and skipping those that clearly seemed to refer to the bottom part of the page (“below the fold”).

I opened the appropriate CSS files and copied these selectors to my critical CSS. In this way I created the first version of my critical CSS. Unfortunately, it was not correct: when I loaded my page, my browser displayed its first version and about a second later the text on it visibly jumped as the deferred CSS was loaded.

I downloaded the page with Wget and created two versions of it: the original created by Wget and another one from which I stripped the references to all external CSS and JavaScript. I compared the pages with the browser and found that they were visibly different. I inspected them with Firebug, found in the html tab of Firebug the elements which were different, found and compared their styles. In this way I found what I was missing in my critical CSS, added it there until there were no differences.”
Baruch Youssin

Optimize Images

Google’s optimize images warning can be frustrating. This warning seems like it should be one of the easiest to fix via one of the great auto optimization plugins available, but even using these Google finds a way to complain that the compression isn’t up to its standards. In fact, even with optimized images Google will make sometimes wild claims about how much savings can be had by further optimization. For the record, I use and really like the EWWW Image Optimizer plugin. If you are using Jetpack you might want to try the free Photon service, which will not only compress your images but also serve as a completely free CDN for them (though according to PJ Brunet the compression Photon does also doesn’t make the grade with Google).

Honestly, I still don’t fully understand what lies behind this test but I have learned enough to at least eliminate the warnings for my site and I will share that knowledge with you. If you have more conceptual insights, please do share with me and others in the comments.

One thing to consider is the image type. I still don’t know if Google has a preference for PNG or JPEG, but it does seem to regularly hate GIF images. So, if you are using those you may want to convert them. Some of the optimization tools (online and computer-based) offer this ability and you can even use Microsoft’s default Paint program if necessary. Note that I came across one commenter that recommended using progressive images. I hadn’t even heard of that before and I wonder how many browsers support it.

Another suggestion I came across is to inline your images in your HTML. Again, this is something I had never heard of doing and I suspect has several drawbacks, including the fact that Google probably cannot index these images, they cannot be browser cached and they cannot be linked or pinned. So, I never really investigated this, but if you are interested, this guide for embedding images might be helpful. That article recommends A Blue Star for converting images to Base64 encoding, though duri.me is another option with a nicer user interface.

A much more common suggestion is to combine background images in CSS Sprites. Doing this lets you load only one graphic file instead of multiple files. My theme doesn’t use many images (it relies more on Font Awesome) so I haven’t tried this, but it might be a good solution for your site.

One of the best ways I have found to silence the optimize images warning is by lazy loading your images. Lazy loading just means that an image isn’t loaded until it is needed. Technically, lazy loading images has no impact on image optimization but images found beneath the fold do not seem to trigger the Google warning. Yes, perhaps this is a bit of a cheat, but it is also a legitimate tool to use because it will delay loading images that might not even be seen by a user that doesn’t scroll down your page, thus speeding things up. There are specialized lazy loading plugins like a3 Lazy Load but my favorite plugin, Speed Booster Pack, also offers this functionality. Of course, you should optimize all your images, but with lazy loading you don’t have to lose sleep about differences of opinion between your optimizing plugin and Google.

One thing to note is that image optimizing plugins only apply to files in your Media Library so make sure anything not in your library is manually compressed. There are a lot of useful tools to compress images, both online and offline. My favorites are the ones that will perform multiple levels of compression and show you each so you can easily decide which one has the best tradeoff of size and image quality. Below are some online compression tools worth considering:

  • Compress PNG (did a good job with the one file I tested but have to download to see the full result; also has a JPEG option)
  • Compress Image (* my current favorite because it handles multiple image types and lets you select the amount of optimization you want)
  • Dynamic Drive Online Image Optimizer – GIF, JPG, and PNG (will optimize and also lets you convert from one format to another. The output shows you the various levels of optimization and you can choose the best for your needs.)
  • JPEG – Optimizer (let’s you specify the compression level)
  • JPEG – Reducer (produces 3 different thumbnail sizes and shows you results of 5 different compression settings, which you can compare and download to suit your tastes)
  • Online JPEG Optimization Tool (no real options for this one and one image I uploaded actually produced an “optimized” image that was larger than the original)
  • PunyPNG (need a paid subscription to download more than basic optimized images)
  • TinyJPG (great results for the one file I tested but you have to download the converted file to see it)

There are many offline options as well. One I recently read good things about is PNGQuant; specifically, I read that it does a good job of eliminating the Google warnings when using the 80-90 setting.

Whichever tool you use, here is a tip: look at what Google thinks you can save (it will tell you in percentage) and use that percentage in the image optimizing tool settings.

Speaking of Google trying to be helpful, did you know when you get an optimize images warning PageSpeed Insights will provide a link to download optimized images (as well as CSS and JS resources) for the page being tested? In my limited testing, the images were in PNG format but I don’t know if that is the only format Google provides or if it was the specific nature of the pages I was testing. I am also still not sure what to make of these Google-provided images because on at least one occasion a file I downloaded from Google was significantly bigger than my original! Also note that Google isn’t the only test to provide this feature as GTmetrix does as well, though I only learned that after I finished my optimization efforts so I haven’t really investigated the quality and usefulness of those.

One other thing that might generate a Google warning is using the same image for desktop and mobile, since the mobile version will typically be sized down from the original. The solution for this is to have different image sizes for different screen resolutions (accomplished via @media CSS rule). That way, if you need a 200x200px image, the browser will download only that size.

A similar issue arises with any resolution when your image is scaled by the HTML rather than using a copy of the image with the proper dimensions. This can especially happen with thumbnails. It shouldn’t happen with well-coded themes and plugins, but the world isn’t perfect. If you suspect a warning might be caused by this HTML scaling, you can check it quite easily. Using Google Chrome, right-click on the picture and choose “Inspect element”. There you’ll see what size it should have and the actual size of the image.

Other images that will cause optimization woes are the emoticons that are now included by default with WordPress. Actually, I don’t know if that is completely true. I know that the simple-smile.png image triggers Google’s warning but this is also a 72×72 image that is typically scaled down and perhaps that is the real cause of the warning. I don’t really know how to address this issue because these are core files found in the wp-includes folder so even if you manually optimize them they will be overwritten when you update WordPress. Perhaps we can localize these images as we have done with other scripts, but if the problem is the resizing not the image itself, this won’t help much. One final option would be to write a function to search for the instances of the offending images and replace them with properly sized local copies, but I am not prepared to go that far right now.

Finally, many Google AdSense images are not optimized and will cause a warning. There is an option when creating or editing your AdSense code to accept text-only ads, which can help with this. Whether there will be any financial performance affect for doing so is another question.

Minify Resources (HTML, CSS, and JavaScript)

This rule triggers when PageSpeed Insights detects that the size of one of your resources could be reduced through minification, which is a process of removing unnecessary white spaces, tabs, carriage returns, newlines, comments, and other unnecessary characters from a file. For JavaScript, minification will also change some variables and object names to shorter ones.

Quite a few of the optimization plugins offer minification but I have noticed that many of them have one or two shortcomings. The first is simply that, while a file does get minified, the end result isn’t quite good enough for Google. There are multiple approaches (and code functions) that can be used to minify, and it seems some are better than others. The second problem is that many plugins minify CSS and JavaScript but not HTML Since Google checks all three, this is not good enough. Unfortunately, my search for a plugin that would minify only HTML was fruitless.

Another interesting thing I noticed is that some plugins do an especially good job minifying one type of file but not another (I found this to be the case with W3TC, for example). This may be fine if you are using more than one plugin that can get the job done in partnership, but a single solution would be ideal.

Something else to worry about with a plugin that minifies is that it may create one or more new files with the minified code. If these are not loaded asynchronously they will trigger a render blocking warning. W3TC is strange in this regard because, while it will let you asynchronously load the combined JS file(s) it will not do so for the CSS file. Fortunately, Speed Booster Pack offers options to both minify CSS and load it asynchronously, so you could combine that plugin with W3TC, disabling the CSS minification in the latter.

One general warning I offer is that minification can sometimes cause serious problems with your site. This is almost always due to minifying JavaScript rather than CSS or HTML. Always test your site thoroughly after enabling a minifying solution.

Minify with Care
“Many users activate a minify plugin and expect it to just work. This is simply wrong on many levels. Minifying is like a driving a Formula One car, it’s extremely fast but dangerous at the same time. If your site has more than 40 Javascript files, or a huge number of daily visitors, an on-the-fly minifying solution (such as one provided by BWP Minify) must be used with great responsibility.

Not all files can be minified, i.e. they simply break when minified. Some are minifiable but break as soon as they are combined with other files (see BWP Minify’s compatibility report for more info).

This is one of the main reasons why a JavaScript function does not work at all or your site look messed up when minifying is active. To resolve that, you need to identify what files are causing troubles. Problematic files can be detected by excluding files one by one in the minification list.

Files that are already minified should not be minified again, to save processing time and in turn improve server response time. Typical examples are files enqueued internally by WordPress, such as jQuery and jQuery-migrate.”
– “WordPress Minify – Best Practices” by Khang Minh

After all my testing, I have come across a few solutions that I think minify fairly well:

  1. Cloudflare. The free Cloudflare plan offers a minify option for all three file types and it seems to work quite well. If you are planning to use Cloudflare, this is the simplest effective solution.
  2. Autoptimize. Many people rave about this plugin and apparently it does a very good job of minifying with one exception. According to Baruch Youssin, while “Autoptimize promptly removes extra white space in HTML code created by WordPress or its plugins, it does not remove extra white space that users enter by hand in their posts and pages.” His suggestion is to manually minify your posts via an online tool like HTML Minifier or Pretty Diff Minifier. Personally, I prefer a solution that doesn’t require so much manual effort, but different strokes for different folks.
  3. PHPWee. PHPWee is an open-source PHP minifier that I came across which is fairly easy to use and quite effective. Below I will detail just how you can use it.
  4. Use Only Child Theme, Minified JavaScripts. If, for some reason, the above options don’t get the job done, you can always do things manually. The process is basically like this:
    • Find the offending scripts listed by PageSpeed Insights
    • Create a copy of those scripts in your child theme.
    • Use an online minify tool to tidy them up.
    • Dequeue the original scripts.
    • Enqueue your new minified version of those scripts.

    I already discussed doing this with two JavaScript files that needed to be minified but were getting ignored by most of the plugins that offer a minify feature. I could never determine why they were getting skipped but I decided that the easiest thing for me was to follow the process above.

Before explaining PHPWee, I should point out that yet again Google AdSense proves to be a nuisance in terms of this PageSpeed test. As I mentioned earlier, the core AdSense script occasionally requests that other scripts get loaded (notably expansion_embed.js and show_ads_impl.js). For whatever reason, these scripts are not optimized in Google’s eyes (more irony here).

With the exception of Google AdSense, my site doesn’t rely on any external JavaScript files that need to be minified. If yours does, the solution would be to try and localize the script, as I discussed earlier using Google Analytics as an example.

How to Minify HTML with PHPWee

Since I still haven’t decided if I want to use Cloudflare for all my sites (I am definitely leaning towards doing so), I needed a good minify solution, especially for HTML. Unfortunately, Autoptimize’s HTML minification wasn’t good enough and I cannot use W3TC with Falcon Engine. So, I had the idea to do my own HTML minification manually in my child theme functions file. I found an article with code to minify without a plugin, and I gave it a try and the result looked good, but it still was not good enough for Google. So, I did some more searching and found an open-source PHP minify project called PHPWee and decided to give it a try. The results were good and my Google warning went away.

If you would like to manually minify your HTML like I did, here’s how. First, download PHPWee (look for the Download ZIP button on the right sidebar) and unzip it to your child theme. The default folder name is phpwee-php-minifier-master but I renamed mine to phpwee-php-minifier. Now, add the following code to your child theme’s functions file:

That should be all you need unless you use Speed Booster Pack and its “Load CSS asynchronously” and “Minify all CSS Styles” options (in the “Still need more speed?” section). Unfortunately, using these options with PHPWee broke my site design. At first, I thought I would just de-activate the minify option on Speed Booster Pack but keep the asynchronous option. Unfortunately, this didn’t solve the problem. Fortunately, the solution is easy. Open the file HtmlMin.php found in the php-wee-minifier/src/HtmlMin/ folder and look for the following line:

and change it to:

That’s it. Now PHPWee will skip any CSS code and thus the minify feature of Speed Booster Pack will be unmolested. If everything works well, you should see nice, compact code with a comment line at the very end telling you how much your HTML was compressed.

Other Changes and Tips

I think I have covered all the essential tools and techniques to get great speed and performance from your WordPress site, but here are a few more things I have come across that might also be useful.

SPDY, HTTP/2 and Google PageSpeed Module

Technologies like SPDY, HTTP/2 and Google’s PageSpeed Module can potentially increase the speed of your website. I am not very familiar with any of these and I don’t know how long it will be before any or all become commonplace, but according to one source they may become game changers in terms of how to get a good PageSpeed score:

“I’d be real careful right now with optimising WordPress or any website, HTTP2 is coming along and most clients already support it. The old tricks combining CSS and JS won’t be as effective. We already see that nearly all of our traffic comes from browsers modern enough to support SPDY. Not only that, some performance tools like pagespeed insights aren’t using SPDY so you’re not getting a true picture. The pingdom tools do use SPDY so I like to know I’m in the top 1% by their measurements.”

loadCSS

If you end up having one or more CSS files that Speed Booster Pack cannot load asynchronously, you might try loadCSS (ref: Loading CSS Asynchronously, which incorrectly states that this is a plugin). I haven’t tried it yet because I haven’t needed to, but I am keeping it in the back of my mind for a rainy day.

Remove Query Strings

Many caching solutions ignore external resources (scripts) that include query strings. Removing query strings is a low-risk (but not no-risk) action and easy to do. Many optimization plugins include this feature so if you are using one that does, simply enable it. You can also choose a special plugin for just this duty, but honestly the code required is so easy that I recommend doing it manually instead. For the code and more background, read Paul Underwood’s post, “Remove Query String From Stylesheets In WordPress.”

Optimize Your WordPress database

In addition to regularly backing up your database, you should occasionally optimize it as well. Frankly, I doubt this will make much (if any) difference in your site performance but I mention it just the same. My preferred plugin for this is WP-Optimize.

Speaking of the database’s role in site performance, “Speed up WordPress, and clean it up too!” by Joost de Valk is an old article but worth reading if you are trying to understand how and why WordPress makes so many database queries.

Spiders & Bots

If you are on a shared server, numerous visits from search engine spiders and bots can increase the load on your server and possibly affect performance. This isn’t really something that will affect any of your test scores (unless you run a test when you are getting hit hard with spider requests, an unlikely scenario). Still, as part of an overall optimization effort you should consider what bots you want to allow, how often they can visit, and which pages and/or content they can see. Chris Christensen’s article, “Increase WordPress Website Speed for Free (using .htaccess and robots.txt),” offers some good advice in all these regards.

Some Observations from My Optimization Efforts

Here are some notes I made regarding some of the plugins I tried. Note that just because they behaved a certain way for me on my site, that doesn’t mean the same will necessarily be true for you. In fact, I wouldn’t be at all surprised if some of my observations were a result of me misconfiguring something. Still, I think some of the observations are worth sharing so here goes:

Async JS and CSS

This script is intended to eradicate render blocking errors but it didn’t for me because it ignored and left in the header the following two scripts:
jquery.js?ver=1.11.2
jquery-migrate.min.js?ver=1.2.1

This script doesn’t appear to minify JS at all, rather it just combines them and moves them to the footer (optional).

Autoptimize

I find that using the “Optimize JavaScript Code” option works well (no conflicts) with Speed Booster Pack and does get rid of any minify warnings for local JavaScripts without creating a separate file with a render blocking warning. Its HTML optimization seems to work well when I view the page source code (looked quite similar to the W3TC minified code), but for some reason, at least on my site, it did not clear the minify HTML warning from Google.

Better WordPress Minify

Better WordPress Minify is a popular minifying script that could be an alternative to WP Minify Fix, especially since it uses the same PHP Minify technology. In fact, I think in some ways it is a nicer plugin (better documentation, a listing of all identified scripts, better configuration options, etc.). Unfortunately, it currently has not implemented HTML minification so for me it is not a viable option. This is on the developer’s to-do list so in the future this might be a great option.

One strength of this tool is just how much you can control with it. The “Manage enqueued Files” options tab lets you see what JS and CSS files are enqueued, listing their handles, position and script location. You can select any file individually and choose what to do with it (change position, move to header, move to footer, not minify, remove). I haven’t really tested it, but I guess the remove option will let you avoid the manual dequeue work I described as well.

Unfortunately, this plugin does not offer any option to load scripts asynchronously or with the defer option (though the developer has stated it is a planned feature). Additionally, it creates its own script that must be loaded (which contains numerous combined scripts) and since these are not loaded asynchronously you also get render blocking warnings.

Considering the nature of this plugin and the nature of Async JS and CSS, they may be a good combination.

Cloudflare

I am still not entirely sure what “Rocket Loader” does, but I use it and haven’t had any problems.

If you use CloudFlare with W3TC, be sure not to enable minification on both. I don’t know which does the best job and perhaps each does a better job depending on the type of file (HTML, JavaScript, CSS) but I think if you use Cloudflare’s “Auto Minify” option you won’t be able to use the option to eliminate the render-blocking scripts in W3TC so if you get that error, perhaps W3TC is the better option. As always, test for yourself.

I already mentioned this, but using the “Page content protection” feature found in the Scrape Shield plugin will trigger the browser cache warning.

Hyper Cache

I had to manually update the WordPress configuration file.

Creates separate caches for desktop and mobile devices.

I am not sure this actually worked properly for me since I didn’t see any improvement in server response time. Since it seems to offer nothing but pure caching and there are other plugins I like for that, I didn’t bother investigating.

Speed Booster Pack

This is my favorite plugin. It offers a lot of features and is very flexible about tweaking the options, though you have to invest a small amount of time to learn exactly how. Take the “move scripts to the footer” feature as an example. You can exclude up to four scripts, which can be useful for “above the fold render” problems. But, you need to enter both a handle and the script to do so. And, the script should be the complete line of code not just the URL. In fact, that field should really be labeled something like “code to implement” because whatever you put there will be inserted into your page code where the original script would have been. This is actually great, because you could leave it empty and effectively dequeue a handle. Or you could reference a localized copy instead of an external file or even add an “async” option if you prefer that to the deferred loading feature the plugin offers.

The only feature I would like to see added to this plugin is solid minification.

W3TC

I previously used W3TC and it is immensely popular. I still regard it highly, but I think it is only worth using if you really take the time needed to learn its ins and outs (e.g., use manual minify rather than automatic and specify every script to minify in correct order, in the proper location and deferred or asynced).

W3TC is great for minifying JavaScript and HTML but if you use it to minify CSS you will get a render blocking warning so you should choose another plugin for that function (there is an inline CSS option, but I presume that means that any inline CSS will be minified rather than meaning that the final minification will be written inline). Many say W3TC and Autoptimize make a good pairing.

If you prefer to use a different plugin for caching (I really like Wordfence’s Falcon Engine), it probably won’t play nice with W3TC, even if you are not using W3TC for caching.

WP Fastest Cache

After reading good things about this plugin, I was left unimpressed, largely because some key features (e.g., “create cache for mobile,” “minify JS,” “enhanced minify HTML,” “enhanced minify CSS”) are premium only. Honestly, there are some good free caching plugins so you have to offer something really great to justify a $40 premium version and this isn’t it.

It created three minified CSS files (thus render-blocked) with no option to inline and one of them still didn’t pass Google’s minify test.

The minify HTML didn’t pass Google’s test.

Because the mobile cache option is premium only, the results on Google’s mobile test are woeful.

WP Minify Fix

WP Minify Fix is a plugin that replaces the unsupported WP Minify plugin. It can minify HTML, JS and CSS. What is especially great about this plugin is that it can even minify external scripts! Unfortunately, even though its HTML minify seems to the eye to be pretty good, it also fails to remove the PageSpeed Insights warning.

WP-Rocket

Everything I read about WP-Rocket is very positive, but as a premium product I did not personally give it a try (plus, I am very happy with Falcon). I suspect one reason it performs so well is that it is doing more than just caching; it also offers lazy loading, pre-caching (a nice feature I would like to have), and minification.

Wordfence Falcon Engine

For more information, see Wordfence’s Falcon engine documentation page.

If you use Falcon Engine, you lose Wordfence’s live traffic feature. For me, this is not a big deal, and may even be better as it can affect performance and bloat your database size, but if it is a feature you really like, it is something to consider.

Summary

Thanks for reading this far!

This tutorial was 45 pages (18,871 words) in MS Word and took me weeks to write (after even more weeks to learn). I included everything I could think of that might possibly be relevant and useful. Perhaps I added too much? I tried not to get too technical and explain things clearly, but only you can be the judge of that so please let me know if anything I wrote left you scratching your head.

If you found this guide helpful in your optimization efforts, I would really appreciate you sharing it with friends on your social media accounts.

Reference: Useful Articles

There are a lot of articles and tutorials on this topic. Below are some that I found helpful in my own learning process.

  1. The Truth about WordPress Performance [#1/2]” by Andreas Hecht, takes a broad look at the pieces of the optimization puzzle.
  2. The Truth About WordPress Performance [#2/2]” by Andreas Hecht, provides a detailed tutorial on steps to take to improve your site performance.
  3. Why Trying to Get 95+ on Google PageSpeed Insights for Your WordPress Site Will Drive You Mad!” by Raelene Wilson is interesting primarily because it shows efforts that resulted in a less than stellar Google score (especially for mobile) but excellent scored on alternative tests (Pingdom and GTmetrix)
  4. Get PageSpeed 100 by using W3 Total Cache and Autoptimize, Part 1” by Baruch Youssin offers a good, detailed tutorial that also demonstrates quite a lot of general knowledge about optimization issues. A good read to accompany this article and proof that you can get a great score using a completely different set of tools to what I (or others) have used.
  5. How to Increase Website Speed and Make Your Blog Load Faster” by Harleena Singh chronicles the author’s attempts to understand and improve her PageSpeed Insights score. The article is written from a tech novice’s perspective and offers specific tips for working with W3TC, CloudFlare, and Wordfence’s Falcon Engine.
  6. Speed Up Your WordPress Site” by Chris Burgess
  7. If you’d like to know more about enqueuing, a couple of good (but perhaps a bit technical) articles are, “How to Include JavaScript and CSS in Your WordPress Themes and Plugins” by Japh Thomson and “The Ins and Outs of The Enqueue Script For WordPress Themes and Plugins” by Jason Witt.
  8. Optimize CSS delivery” and “Eliminate render blocking css” by Patrick Sexton offer a good overview of issues involved with CSS.
  9. More Optimization Techniques for Improving Website Speed” by Pedro Semeano
  10. Benchmarking the Fastest WordPress Cache Plugins” by Philip Blomsterberg shows testing results for a 20 different WordPress caching plugins (though using nginx not Apache). TL;DR: WP-Rocket was the winner with WP Super Cache, W3 Total Cache, and WP-cache.com all performing admirably.
  11. WP Super Cache Vs W3 Total Cache Vs WP Fastest Cache Vs Hyper Cache Vs Quick Cache Vs Wordfence Security
  12. WordPress Caching Plugins – The What, How and Why” by Sorin
  13. The Best WordPress Caching Plugins and Why Testing Them is So Important” by Kevin Muldoon
  14. Speed up smaller websites by migrating them to CloudFlare Free” by James Sanders discusses how websites can benefit by signing up for CloudFlare Free.
  15. If you decide to use Amazon’s Cloudfront CDN, two useful articles are Daniel Pataki’s “Moving WordPress Media To The Cloud With Amazon S3” and my own “Speeding Up Your WordPress Blog with W3 Total Cache (W3TC).” The first details how to setup Amazon S3 and Cloudfront (both needed) and use the Amazon S3 And Cloudfront plugin. The second discusses using Cloudfront with W3TC and—more usefully—offers detailed instructions for setting up a CNAME so that instead of your images showing amazon.com or cloudfront.net URL locations you can have them show something like media.yourdomain.com. This is better for both SEO and usability.
Like this content? Why not share it?
Share on FacebookTweet about this on TwitterGoogle+Share on LinkedInBuffer this pagePin on PinterestShare on Redditshare on TumblrShare on StumbleUpon

25 Comments

    1. Looks interesting but just gave it a quick try and you need to register to see detailed test results. Not a big fan of that, especially since the other tests don’t require it.

      1. Thanks for the feedback. I understand, but registering allows you to create a free monitoring, and I can ensure you we do not send a lot of emails (except monitoring alerts and weekly monitoring digests). Moreover, you’ll be able to disable our “marketing” emails from your profile.

        1. I understand, but I am not interested in free monitoring and not sending a lot of emails can’t compete with not sending any, which is what you get with other tests that don’t require registration. If the other tests were not very good maybe it would be a harder decision, but those tests are all excellent. What does yours provide that is different? I don’t mean to be critical, I genuinely want to know. Perhaps knowing that would make myself and others more comfortable with registering.

  1. “but those tests are all excellent”: of course we’re not as affirmative as you on this ๐Ÿ˜‰

    So, here is what you will get using dareboost.com:
    – some checkpoints that are not available anywhere else, about pro tips (for example, this http://calendar.perfplanet.com/2014/the-pain-of-duplicate-scripts/)
    – some checkpoints dedicated to the technologies used by your website (you’re using JQuery? We’ll check performance best practices in your jQuery code
    – some “generic” checkpoints, customized for the technologies used on your website (you’re using WordPress? Your CSS is not minified neither combined? We will tell you about WP Rocket)
    – some metrics you will not find on other tools listed below (performance timings for example, and in a couple of weeks, we will add SpeedIndex, VisuallyComplete, etc)
    – we’re not only dealing with performance, for us performance is a major part of web quality, but we’re looking for all front-end technical issue (SEO, compliance, security, etc)

    And yet we provide this for free for homepages. We ask an email, because our product is young and we still need to add a lot of amazing features. Getting users when other tools are famous is not easy, so we want to be able to keep our users informed as long as our product evolve ๐Ÿ™‚

    1. Well, I’m into this as a advanced newbie who was totally confused about what to do in the real word about all the magnification issues I’d like to see this tools opinion. And free too, thanks. ๐Ÿ™‚

      Most thanks to JB for this AMAZING article/tutorial!! I am excited to get started.

  2. Thank you for this in depth piece of content! I’m not so technically skilled when it comes to coding but still I have been trying to optimize my google page speed score for weeks. Just last week I discovered the Speedbooster plugin and in addition with the W3 total cache plugin I was able to get a 100 % score for my most popular pages just about an hour after I installed it. Really impressed by this plugin. I haven’t been able to get a 100% for my homepage, but that’s mainly because of external services (like Google itself!) and I’m not too worried about it because multiple speed tests confirm that my homepage loads in less than a second.
    I actually arrived at your page because I was googling to find out if the speedbooster plugin is compatible to do A/B testing in Adsense. There doesn’t seem to be much info on that. Would you happen to know the answer?

  3. For a couple of months, I have try to search how to 100/100 google pagespeed with wordpress with google. I have read more than 15 article about this. And this is one of the greatest article how to optimize the wordpress page speed I have ever read,

    Dam* you google, why you don’t put this article in the page one of your search result.

    If you are not mind, could you use twenty fifteen as a default theme as your research?
    I have tried optimize twenty fifteen theme, but only got 82 (mobile) and 92 (desktop) point in google pagespeed with nginx webserver.
    Now i tried to look optimizing with litespeed webserver.

    Another reference I found about 100/100 google pagespeed is from mattyl.co.uk/2014/06/15/how-to-score-100100-with-google-pagespeed-insights-tool/ with twenty fourteen themes and nginx webserver module.

    Thank you so much, I hope you always have a wonderful days because of this article.

    I know 18,871 words is a looooooooong article.

    Again, “Dam* you google, why you don’t put this article in the page one of your search result.”

    1. Sorry, I somehow missed this comment but thanks for the kind words. Well, I am not actually a developer so this was all for hobby and my own benefit, so the idea of using twenty fifteen as a default theme to replicate this work doesn’t sound like too much fun for me ๐Ÿ˜‰

      I have read many people discuss the merits of nginx/litespeed and I am sure they aren’t necessarily wrong, but my basic attitude is to use what the most people use so when problems arise (they always do), it will be easier to find answers. If your technical ability is such that this isn’t a concern, by all means, try that out, but as I have demonstrated, you CAN get 100/100 on regular old Apache on a shared or low-end VPS system so I don’t think a drastic OS switch is really necessary or even the best use of your time and the result is far from certain anyway. Good luck with your efforts and report back if you have success.

  4. That’s an amazing piece of work! It’s going to take me a little time to digest a lot of it!

    You picked up on some remarks I’d made about HTTP/2 and I wanted to underline that again. A lot of the conventional wisdom about tuning for webpages in general and WordPress in particular are really about overcoming shortcomings in HTTP/1. So, already we’re seeing that the speedtests are due a huge overhaul. In terms of mod_pagespeed, it’s true that it’s a powerful and (I think) under-utilised tool, but it’s also true that some of the features there are also fixing problems that aren’t there with HTTP/2. But I am certain, once it’s installed, it’s an easy way to optimise images and deploy a CDN.

    You quickly mentioned database optimisations which was the right amount of weight to give it. Most wordpress database optimisation is based on a seriously broken understanding of how databases work. I wrote another post on that :

    https://www.alpine.link/making-wordpress-faster-database-optimisation/

    And of course, if you’re page caching then database queries aren’t a significant part of page load time anyway!

    1. Interesting read, Ian, thanks for sharing. And, did you notice that last week Cloudflare announced they are activating HTTP/2 by default for all free plans? That seems promising, and confirms what you originally wrote that it is coming along.

      1. I see CloudFlare have also published a blog about this :

        https://blog.cloudflare.com/http-2-for-web-developers/

        That says more or the less the same. People don’t always see web performance issues in terms of protocols but it’s all about how limiting HTTP/1.1 was.

        The key thing though is that HTTP2 in browsers is already really, really big. If you turn it on then the majority of clients will use. The older ones fallback to HTTP/1.1 naturally. The challenge is that you have to strip out the old tune-ups for the new clients to work well, now the smaller number of old clients aren’t optimum.

        If you’re operating in the developing world this is a big deal. On a related note, FaceBook has pushed back on SHA1 retirement due to similar concerns. ie

        http://arstechnica.com/security/2015/12/sha1-sunset-will-block-millions-from-encrypted-net-facebook-warns/

        But in the developed world we’re talking about people with older versions of software. Although, not always, I couldn’t get HTTP2 to work OSX Yosemite and Safari (it did with Firefox). Yosemite adoption runs at 43%, you’d need to slice the other 57% to figure out what their browser is but I think we’d guess substantially Safari users. Even so, you can argue about 50% of mac users are on HTTP/2 support.

        I’ll try and make sense of our logs sometime, we record HTTP version by way of nginx logging.

    1. Sorry but I am not sure what you are trying to describe exactly. Are you saying one of the optimization plugins is stripping spaces? If so, which one? If I have to guess, it would be a minification solution.

      1. Apologies for the bad late nigh commenting.
        Yes, the current version of PHPWee sadly is removing some spaces which should be preserved, was just wondering if you knew which version you have here as its not happening on your site.
        Cheers

        1. Well, the latest version is quite old so I think we are using the same one. I have made some tweaks so that might explain it. In reviewing my src\HtmlMin\HtmlMin.php file, I see that I made a modification because I was having problems with stripping out spaces before some URLs – not sure if it is the same issue you are having or not (may be and I didn’t notice it or failed to comment about it). One way to find out, give it a shot by commenting out the line:
          $c->nodeValue = trim($c->nodeValue);

          Do let me know if that helps.

          1. Glad it helped. I was also going to mention it on Github and noticed you (and another) had already done so. Hope they fix it since, to be completely honest, I have no idea what that line we are commenting out is supposed to do and if we are causing some other unknown problem by removing it.

  5. Here are a couple of new articles on the topic I recently read. They don’t necessarily cover anything not included in my post, but for those who like to be thorough they might be worth reading:

    Google PageSpeed Insights โ€“ Scoring 100/100 with WordPress
    https://www.keycdn.com/blog/google-pagespeed-insights-wordpress/

    How to Achieve 100/100 with the Google Page Speed Test Tool
    https://moz.com/blog/how-to-achieve-100100-with-the-google-page-speed-test-tool

  6. Thanks for the tip and example for using PHPWee. This nifty little extension just increased my page speed score to 97 and gtmetrix to 98/97

    1. I’m glad to hear the article was useful to you. FWIW, I have now switched my setup and am using Autoptimize, which also has a good HTML minify function so something to consider for the future if you decide to change things up. I will be writing another detailed article discussing what I have learned since I researched/wrote this post.

Leave a Reply

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