How I Got Over A 90 PageSpeed Score

…And why a ‘100’ isn’t always the best option

When I began designing this blog I knew it had to be fast and I just couldn’t stand the idea of having too much bloat. It is always tempting to go the route of ‘theme builders’ but a lot of these customizable themes are heavy with extra features that most websites may not use and add in additional resource calls that may slow your page load if not properly dealt with.

So I coded my theme from the ground up. Utilizing TeamTreehouse’s tutorial Bootstrap to WordPress Theme I slowly pieced together a functioning website.

I felt I was on the right track, but my concerns were not being addressed; I wanted this site to load in under two seconds. After running my site through Google Pagespeed Insights, GTMetrix and Varvy.com I took note of the main issues.

Varvy and Google essentially gave me the same information so here is a quick copy paste from Varvy.

 

Server:

Quick server response time
Compression not enabled
Browser caching issues
Keep-alive not enabled
Minimal redirects

Page:

No bad requests
HTML not minimized
Request size is fine
Visible content prioritized
Render blocking CSS / JS found

Resources:

Images not optimized
Javascripts seem async
 CSS minified
No @import CSS
JS minified

Apparently, my website was hurting in a lot of ways. Using this baseline I set out to methodically correct each issue. I will go step by step through these common issues and then list some helpful plugins at the end. These plugins should assist those of you who are hesitant with editing your code.


Server

Compression

Enabling compression on your server is a vital step towards decreasing load speed. Enabling compression allows your server to send smaller files, thereby speeding up your website.

The average user can enable what is called Gzip compression. It is very simple and requires adding a bit of code to your .htaccess file via FTP.

Warning! Whenever you are editing your .htaccess file you must be sure to make a copy of the original before you make edits.

Add the following code to your .htaccess file after ##End WordPress:

<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>

Browser Caching Issues

Browser caching is a great technique that helps us avoid loading the same files over and over. Browsers can cache all sorts of files such as images, favicons, libraries, and fonts.

By enabling browser caching and setting an expiration for your files you are telling the browser to remember an instance of a file until told otherwise.

Here is the code I use in my .htaccess (remember, make a copy before editing .htaccess):

## EXPIRES CACHING ##

ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"

## EXPIRES CACHING ##

Usually, the browser will update its cache when the files change on the server in order for the browser to maintain the most recent version. By utilizing browser caching we can speed up our site by avoiding unnecessary calls to the server.

Enable Keep Alive

Enabling Keep Alive in the header of your site tells the browser to keep the initial TCP connection open for additional HTML conversation. Every time files are requested by the browser, the browser must ask the server if the files exist. The server will respond with a ‘yes’ or ‘no’ and then decide whether to send a file. If Keep Alive is not enabled then this process must repeat itself over and over, thus delaying the page load.

Keep Alive, also known as a persistent connection, is usually enabled for most servers. But if you are on a shared hosting platform it is possible your hosting provider has disabled Keep Alive for performance reasons. We can enable Keep Alive with one line of code in our .htaccess file:

 Header set Connection keep-alive 

Page

Minimize HTML

Minimizing HTML perhaps has the least impact on a site’s performance, but nonetheless it is easy to do and will increase your speed a bit. By utilizing plugins such as W3 Total Cache we can reduce the file size by eliminating superfluous line breaks and characters.

Render blocking CSS / JS Found

This may be one of the biggest changes to a website to reduce the render time. In order for a page to load, it must first download all of the requested resources. But sometimes there are a lot of resources such as CSS and Javascript. There are three things to pay attention to in order to avoid blocking the page render.

All CSS and Javascript should be minified and concatenated (combined) into as few files as possible. The least amount of calls to the server, the faster the page can render.

Javascript should be loaded from the footer*, typically before the closing tag.

All necessary CSS and Javascript that is needed to show the above the fold content should be inlined. Everything after the fold can be deferred with this amazing code by Patrick Sexton:

<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20type%3D%22text%2Fjavascript%22%3E%0Afunction%20downloadJSAtOnload()%20%7B%0Avar%20element%20%3D%20document.createElement(%22script%22)%3B%0Aelement.src%20%3D%20%22defer.js%22%3B%0Adocument.body.appendChild(element)%3B%0A%7D%0Aif%20(window.addEventListener)%0Awindow.addEventListener(%22load%22%2C%20downloadJSAtOnload%2C%20false)%3B%0Aelse%20if%20(window.attachEvent)%0Awindow.attachEvent(%22onload%22%2C%20downloadJSAtOnload)%3B%0Aelse%20window.onload%20%3D%20downloadJSAtOnload%3B%0A%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>">

This code can be placed before the ending </body> tag in your footer.php file. The file defer.js can be named whatever you like, the only thing to remember is that this file will wait till the page is done loading resources and then will be loaded.

Any scripting you wish to defer should be placed in this file. Things such as Google Analytics, social media code snippets, etc can be loaded after the page render and it should benefit your website load speed if you defer them.

*Warning! jQuery and other Javascript libraries should not be deferred because they are large files that other javascript files, such as your theme.js file, require to load first. There are better ways to defer Javascript libraries.


Resources

Minify CSS & JS

Minifying essentially strips a file of all needless line breaks, spaces, and useless characters. A minified file becomes much smaller than the original file, but is also much harder to read. Typically, minified files should only be used in production because they provide the best performance gains.

There are a number of ways to minify your files. WordPress provides a lot of plugins that can do this. W3 Total Cache, BWP, MinQueue are the ones I am familiar with. But as a developer, it is important to become familiar with task runners such as Grunt or Gulp. I personally use Grunt.

Grunt is a great tool based on Node.js. It is very easy to use and it uses two great plugins:
grunt-contrib-uglify
grunt-contrib-cssmin

As you would expect, these plugins automatically minimize your CSS files and JS files.

Grunt can be a bit technical, if you are simply just using WordPress to blog you should consider the WordPress plugins I listed earlier. I typically use W3 Total Cache because it also offers a lot of caching and compression options, but I am quite fond of MinQueue. MinQueue not only allows you to minify your main stylesheet and JS, but EVERY stylesheet and JS file including the ones that are brought in by other plugins. W3 Total Cache can also do this, but it is a bit more involved.

BWP does this too but it doesn’t allow you to exclude files. I have found that sometimes there are files with dependencies that fail to load if they are minified incorrectly, so this level of control that MinQueue offers is invaluable.

Image Optimization

Images and fonts are typically the largest files your website will load. Image file sizes can easily get out of hand if they are not optimized. Serving a PNG or GIF where a JPEG would suffice is a common mistake that can really add up with each image that is uploaded to your site. Optimization of images is about getting the smallest file size without compromising image clarity.

When you upload images, WordPress automatically makes various sizes of the image based on how your theme defines these image sizes. So before you drop an image onto the  page, be sure to choose the smallest image available in order to serve a smaller image file. This will make loading these images that much easier on mobile devices.

As long as your theme is properly coded, WordPress should serve a version of your image that most appropriately fits the gien device. In theory, if you load your website on a mobile device, WordPress will serve a small image rather than the larger image needed for a laptop or desktop monitor.

  • There are a variety of ways to optimize your images:
  • Optimize the image through a program such as Photoshop or Pixlr.com
  • Use a task runner like Gulp or Grunt
  • Use a website like Tinypng.com, Tinyjpg.com to manually optmize each image
  • Convert bulky PDF files to more reasonable JPEGS at https://smallpdf.com/
  • Or use a plugin such as Smush.it, EWWW, Imsanity, or Tiny Jpg & Png.

 

However you choose to do it, please optimize your images for the sake of mobile data plans. Mobile traffic makes up ~56% of search traffic these days, so Google does take notice of websites that do not conform to this new frontier.

Check back for my future post on Image Optimization.

 

Fonts

After installing Better WordPress Minify and using the Google Webfont Loader I checked Pagespeed and was surprised by a stunning 70/100 mobile and 86/100 Desktop. Not bad! The issue with custom web fonts is that they need to be loaded from either an external domain or they need to be hosted on your own server. The difference it that a hosted web font is able to be downloaded from a server that is theoretically closer to your location, resulting is a shorter response time. Unfortunately, you cannot set the cache headers for a resource hosted elsewhere.

On the flip side, if it is a popular font then the user may have already downloaded a copy of it from when they visited another site that also uses the font. The benefit of hosting your font on your web server is that you can cache the font. If you use a CDN, you may be able to also server this resource in a ‘hosted fashion’. This is all debatable.

One major issue with hosted fonts is what they call the FOUT, or ‘Flash of Unstyled Text’. This happens because the text is rendered earlier in the page load than the external font stylings. So for a split second the user sees the unstyled text, this lends itself to a poor user experience.

It isn’t possible to avoid this if you are requesting the style from an outside domain. Another issue is that the font requests can stop the page load until the styles are downloaded. This is also bad because it delays the page render. By using the Google Webfont Loader, we can asynchronously delay the download of these fonts till after the initial page render. This greatly improves your load times.

Suggested Plugins

I highly recommend the following plugins:

Caching

W3 Total Cache

MinQueue

BWP

Image Optimization

Smush.it

Compress JPEG & PNG

EWWW Image Optimizer

Imsanity


In summary

It is important to optimize your website so it loads in under 2.5 seconds, Google even accounts for it as a ranking factor. Reaching a Google Page Speed of 100 can be a fun activity, but do not let it govern what you spend your time on. There are lots of small factors that make up these rankings and sometimes it may be preferrable to have a feature that doesn’t quite fall under a proper page speed dictation in order to give that feature to your users. We create websites for people, not robots, so if your user experience is great then a 100 on Google Page Speed may be a wasted effort, especially when any number of changes to your website can cause that ranking to inadvertantly drop. Focus on limiting calls in the above the fold content and optimizing your images, these two things are the foundation of a well optimized site.