The Truth About WordPress Performance [#2/2]
In the first article of this series, we talked about all important points for a perfect on-page performance optimization. Now you know what you need to adjust to speed up your WordPress website. Although, it sounds pretty easy in theory, it can be quite hard to put into practice. Therefore, we’ll go together through all points to make sure you apply everything right. To be clear: This article covers how to speed up a WordPress website and get a high Google PageSpeed rating.
Analyzing the Initial State
For this test I choose a clean WordPress installation with imported theme unit test data in order to simulate a comprehensive blog. My favorite WordPress theme is Baskerville by Anders Norèn because it needs pretty much CSS and JavaScript. In addition, I assigned each article an article picture. This simulates a long-existing well-kept blog. Also, I installed the Jetpack plugin and activated exactly the same points like I did on my website (TechNick – which has 93 of 100 Google Page Speed points). This has the advantage of optimizing a website similar to a regular rea life installation as more CSS, and JavaScript files can be found within the HTML source code. We don’t want the optimization to be too easy. Active on Jetpack:- Photon
- Publicize
- Sharing
- Shortcode Embeds
- Site Verification
- Subscriptions
- WP.me Shortlinks
- WordPress.com Stats
1. Before Getting Started: Create a Child Theme
Before we get started, you should create a child theme and activate it. Direct changes on a theme only make sense if you created it yourself, and hence it won’t be updated. For all other themes, you’d be better off using a child theme since you’d lose all changes with a theme update and nothing would run as it should anymore. The WordPress Codex has a great instruction how to create a child theme. It’s important not to load the CSS file of the parent theme through the CSS file of the child theme via@import
. This is not only bad style, but it’s against the WordPress guidelines and causes one more HTTP request – which we want to avoid.
Load the CSS correctly via functions.php
of the child theme. This is how to do it:
function enqueue_parent_theme_style() {
wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css' );
}
add_action( 'wp_enqueue_scripts', 'enqueue_parent_theme_style');
The CSS stylesheet of the child theme needs to be loaded correctly as well, and must not be linked in the header. The code should be incorporated into the functions.php of the child theme and added to the header.
/**
* Proper way to enqueue styles and scripts
*/
function theme_name_scripts() {
wp_enqueue_style( 'style-name', get_stylesheet_uri() );
}
add_action( 'wp_enqueue_scripts', 'theme_name_scripts' );
The child theme folder should contain a CSS file called style.css and a file called functions.php. A screenshot would help to easily find the child theme. Now, upload your fresh child theme via (S)FTP into the wp-content/themes folder on the server. Go to the WordPress admin interface and activate your child theme. If you’ve done it correctly, your HTML source code should contain three CSS files:
- parent-style-css
- style-css
- jetpack_css-css
2. Test the Performance and the Google PageSpeed Points
In order to understand the effects of the changes, you will need to analyze the initial state. Use Pingdom Tools and Google Page Speed Insights to test the website without any optimization. Don’t forget to click on Amsterdam (if that's your nearest location), which you can find below the URL bar in the settings. Initial state with Pingdom Tools: Initial state with Google PageSpeed Insights: 68 of 100 possible points is bad. So, there’s enough room for optimizations.1. Tune the .htaccess File
Before we start, let’s have a quick look at the WordPress .htaccess file and add some lines of code. You can find the .htaccess file in the WordPress main folder on the server where the folders wp-content, wp-admin, etc. are located. Load the .htaccess to the desktop and paste the following below “End WordPress”:################### Activate compression ###### AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript ################# Activate browser caching ###### ExpiresActive On ExpiresDefault "access plus 1 month 1 days" ExpiresByType text/html "access plus 1 month 1 days" ExpiresByType image/gif "access plus 1 month 1 days" ExpiresByType image/jpeg "access plus 1 month 1 days" ExpiresByType image/png "access plus 1 month 1 days" ExpiresByType text/css "access plus 1 month 1 days" ExpiresByType text/javascript "access plus 1 month 1 week" ExpiresByType application/x-javascript "access plus 1 month 1 days" ExpiresByType text/xml "access plus 1 seconds"The Google PageSpeed test shows the effects of these two entries on the performance: With this tool, you can check if the Gzip compression works. The REDBot tool checks the proper functioning of the browser cache.
2. Optimize CSS and JavaScript
Before you start with major adjustments in the CSS, you should first try minor adjustments like the summary and compression. I check first if the jQuery needs to stay in the header (like it usually does for compatibility reasons). So, I add some code to the functions.php of the child theme which puts all JavaScript files into the footer./** * * Puts all JavaScript into the footer * */ add_action( 'wp_enqueue_scripts', 'evolution_print_jquery_in_footer' ); function evolution_print_jquery_in_footer() { if ( ! is_admin() ) remove_action('wp_head', 'wp_print_scripts'); remove_action('wp_head', 'wp_print_head_scripts', 9); remove_action('wp_head', 'wp_enqueue_scripts', 1); }
Download and Installation of Autoptimize
Autoptimize is a small powerful plugin for the compression, summarization, and minimization of CSS and JavaScript files. It has, in addition, a built-in function for the “CSS above-the-fold” what we’ll need later on. After installing and activating Autoptimize, switch to “Settings => Autoptimize” in the WordPress dashboard and click on all three options: Optimize HTML, CSS, and JavaScript. When you’ve done this, your HTML source code will look compressed but neat. The amount of incorporated files has drastically reduced. I can only find two CSS files (theme and Google Fonts) and two JavaScript files (theme and Jetpack) in the source code of the Baskerville child theme. Download Autoptimize from WordPress.orgDownload and Installation of Cachify
Cachify is a very efficient WordPress caching plugin wich has only a few setting options. It does, however, a pretty good job. Cachify generates static HTML pages from dynamic PHP pages. These can be delivered faster to the browser as they don’t require the PHP interpreter for every call. Cachify is one of the best caching plugins on the market because it’s easy to use and brings good results. The cache is best stored on the hard drive – of the two options this is the faster one. You’ll need to add a code fragment to the .htaccess, however. This and much more tips by the developer Sergej Müller can be found on the Cachify website. Download Cachify from wordpress.orgInterim Results
The Pingdom tools are kind to us and already show decent results. I bet Google PageSpeed Insights won’t be that optimistic! Google appreciates all the effort with only one point since there are still three problems with the test script of which only one can be solved without further ado. Why’s that? Let’s go through all three points: Point 1: Eliminate JavaScript and CSS resources blocking the rendering of above-the-fold content. Easy to solve. This is about finding the points within the CSS necessary for displaying the content above the fold. These CSS parts need to be compressed and added inline into the header. Link the rest of the CSS into the footer, so it doesn’t disturb the page reproduction. Point 2: Optimize Images. Not problem-free with this theme as you need to change the code. First, determine what size the article images on your homepage need to have. If you use 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. As you can see on the screenshot, the image is 600 x 300 pixels and is scaled by the HTML to a size of 359 x 180 pixels. So, we need a correct size of 359 pixels by something. Index.php is responsible for the display of the homepage. If you copy it from the parent theme folder and open it with a text editor, you’ll notice that the content.php of the index.php is loaded. Copy it to the desktop as well and add the following line: Replace this line by, for example:<?php the_post_thumbnail( 'front-thumb' ); ?>In addition, you’ll need to add the following in the functions.php of your child theme:
/** * Image sizes * */ if ( function_exists( 'add_theme_support' ) ) { add_theme_support( 'post-thumbnails' ); add_image_size( 'post-image', 945, 9999 ); add_image_size( 'post-thumbnail', 600, 9999 ); add_image_size( 'front-thumb', 359, 9999 ); }To make sure your changes won’t get lost with the next theme update, upload the edited content.php along with the functions.php into the child theme folder on the server. Now, the images on the homepage need to be assigned anew, so that WordPress can rescale the post thumbnails correctly. Let’s test our website again with Google PageSpeed Insights. Don’t forget: Delete the Cachify cache beforehand (dust bin symbol in the upper right of the dashboard). The new Google PageSpeed Insights result Point 3: Reduce JavaScript. What can I say? This request is nonsense as the JavaScript is already excellently compressed. Just ignore it – it won’t make your website faster. Especially not with the JavaScript being loaded at the end and having been assigned a defer attribute by the plugin (even if it doesn’t make sense because it’s in the footer). Now, there’s only one more adjustment to make if we’re not happy with the 93 Google PageSpeed Insights points:
3. CSS Resources Blocking the Rendering – Let’s Get Down to the Nitty-Gritty
I hope you’re happy to try out new things and like doing fiddly work because we have to try some things to find the best solution. At this point we need to find all CSS content in the stylesheet which is responsible for displaying the above-the-fold content. Download the Style.css from the parent theme “Baskerville” to the desktop and open the file with a text editor. Don’t forget the Google Fonts stylesheet; most themes use Google Fonts to ensure a pleasant typography. Also, create a new CSS file and name it “test.css” or something like that. This is needed only for the copied CSS bits from the Google Font file and the Baskerville theme CSS file. Note: Make a copy of the original theme file before you start editing it. Now we can try out some things and find the CSS, which is necessary for displaying the content above-the-fold. For that, you can use this generator. I chose this way: First, I copied the content of the Google Web Font file. This is important to avoid stutters when fonts are displayed. Then, I copied the CSS points 0 to 7 from the stylesheet.cc of the Baskerville theme (line number 37 to 1240). This CSS (Google Web Fonts and the style.cc 0 to 7) is now to be compressed as much as possible by a CSS compressor. Then I added the highly compressed CSS into the appropriate field in Autoptimize and saved it. If you activate the advanced options, you’ll get the subitem “Inline and Defer CSS” of the item “CSS”. Click on it and paste your compressed CSS. Don’t forget to save it.Remove the Google Web Fonts Stylesheet from the Header
We don’t need the Google Web Fonts in the header anymore, since we have just compressed it along with the rest of the CSS necessary for the above-the-fold content and added it inline into the header. We can remove the Google stylesheet with a few lines of code within the functions.php of the child theme:/** * Deregister and Dequeue Google Webfonts * These fonts are now in the inline CSS * */ function baskerville_remove_scripts() { wp_deregister_style( 'baskerville_googleFonts' ); wp_dequeue_script( 'baskerville_googleFonts' ); } add_action( 'wp_print_styles', 'baskerville_remove_scripts', 20 );Now, the moment of truth has come: The final test with Google PageSpeed Insights.
The End Result of the Test Page
The end result turns out to be only one point behind Smashing Magazine, which has an incredible 100 of 100 points. Yes, I’m proud of it. At the same time, the mobile view has drastically improved, although, we haven’t optimized our site for this.Conclusion
The only point we could still adjust is a better compression of the JavaScript. But this would save us only 673 bytes (1%). This isn’t relevant at all for the performance. To keep going would only mean to massage one’s ego. 99 of 100 possible points for the desktop and mobile view is a phenomenal result. A website with such a result is an exception. If you get to this point, you’re a real artist. I hope my article helps you become that artist and makes your website a real racer.Related Links
- Baskerville Theme - Download from WordPress.org
- Theme Unit Test - Includes download test data
- Google PageSpeed Insights - Speed and optimization
- Pingdom Tools - Speed test
- GZIP Test Tool Checks, if compression works
- REDBot Test Tool Checks, if browser caching works
- Download Autoptimize from WordPress.org
- Download Cachify from WordPress.org
- The Cachify site by Sergej Müller
- A CSS compressor
- Critical Path CSS Generator
Very Nice Post! You have mentioned, jquery may should remain in the head, but how to except jquery from putting scripts in the footer???
Hello Viktor,
why do you want to do that? Makes no sense to me at this point. Whatever, I have no coding solution at this time. But the plugin “Better WordPress Minify” does the job, I think so. A view in the plugin code should then bring the solution.
I do need some jQuery Functions inside Posts and Widgets, but all other Scripts have to go underneath “the Fold” in case of Googles Pagespeed Options…
thx for sharing these great optimizations
A great tut for wordpress performance. How is it compared to other CMSs? Or compared to using nginx probably?
Thanks for the tips, I’m trying to increase my speed score too. Out of interest, shouldnt a decent caching plugin add the .htaccess changes? I’m currently using WP-Rocket and that does it automatically.
i don’t find until today any plugin that do a good job.
for perfect performance in compressing the images, allow the htaccess with compression
and if server is linux-apache exist more compression for allow.
for the google the speed is all.
Good article with some useful tips that I used when I started trying to learn how I could master PageSpeed Insights. In the end, I was able to get 100 (mobile and desktop) on three different sites and I used completely different plugins (Speed Booster Pack and Wordfence’s Falcon Engine, plus some code modifications). Goes to show that there is more than one way to please Google. I wrote a long tutorial on the process for anyone interested in reading:
http://www.lengthytravel.com/how-to-score-100-on-google-pagespeed-insights-a-complete-guide-to-optimizing-your-wordpress-site-performance-and-speed/
One thing that surprised me is that you didn’t generate any warnings for your Google font. I know you moved the code but it still references the original third-party files so I would have expected some warning as a result.