Published: 2017/05/17 Reading Time: 6 minutes

WordPress Performance in Theme Development

WordPress performance is usually very achievable, especially when you control the theme development.I've once again updated my theme, but for good reasons. I wanted to explore two areas of front-end web development that I needed more experience in: WordPress performance in building themes, and the new CSS kid on the block — Grid. This post is a review of the strategies I used in the theme, and how you can leverage performance gains and layout options using modern technologies. If you like the theme, you can get it for free on GitHub.

WordPress Performance is Achievable

WordPress is actually very performant. Forcing server-side rendering used to be an issue, but with the WP-API almost all of the setbacks to performance are no longer forced and therefore invalid arguments. What's more important, is that most performance issues come from bloated themes and plugins. They often times add either large-size assets to the page, or smaller-size assets in render-blocking methods. Usually, it's both. With this theme, I wanted to reign in the excessive default resources that are usually coupled with modern themes and trim everything down to as small as possible. The result? An average ~24kb page size on my homepage, and ~500ms load time. Pretty great results for what many will call a "slow" platform! So, let's get to the meat of how I keep resources low and WordPress performance optimized:

1. System Font Stack

You may have heard about system font stacks around the web. If it sounds scary, don't be alarmed. Chances are, you are using system fonts to some degree no matter which way you go, usually by declaring the fallback font type: sans-serif; at the end of a font family declaration. What people mean when they use the term "system font stack" is really just a declarative way to give priority to the systems default font before any other font is used. The result is no additional bloat (since every hardware device has to have a default font loaded at all times), and very fast render times. This particular release uses the WordPress font stack with a slight modification from Medium:

-apple-system, "San Francisco", BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

2. Bye-Bye jQuery

People tend to hate on jQuery, but there are really only two valid reasons among the myriad of reasons thrown around:

  • jQuery is large. Version 3 fixed this issue significantly by cutting the size in half, but even modern installs of WordPress include 2.x by default. The result is an instant ~94kb asset loaded. What's more, it's loaded in the header and not the footer — meaning that the entire library must download before the DOM will continue to load. This is called render-blocking, and is one of the biggest factors affecting WordPress performance.

  • jQuery is used for more than it was intended. It's true that jQuery "can" do just about everything, but the truth is that it was meant for DOM manipulation. Not state management or virtual DOM creation (storing DOM representations in JavaScript objects). Unfortunately, since WordPress is bundled with jQuery, many plugin developers choose to utilize it's benefits for the sake of convenience — not necessarily because it's a better option. It was these two major issues that caused me to decide to dequeue the script (along with jQuery Migrate), and gain a significant speed increase. Sure, it requires that my entire JS file for the theme is coded in vanilla JavaScript — but I ended up seeing that as a benefit as well. ;-)

    3. Only Load Prism When Necessary

    I use Prism.js to manage syntax highlighting with my code snippets, but the size of the file (though minified) is still fairly large (this theme's particular file is 17.4kb). In my last theme, I just loaded Prism on every page. With this theme, I wanted to load the Prism.js file only if there was a pre or code tag on the page. This required using my regular JavaScript file to do several things:

  • Check if the page has any code snippets.

  • Create the Prism script HTML to inject into the DOM.

  • Inject the script after the Window's load event. To accomplish this, I used the following code:

    // Run the script after the DOM is loaded, but before it is rendered. document.addEventListener('DOMContentLoaded', function() {

    // Check for pre or code tags in the DOM.
    var code = document.querySelector('pre,code');
    
    
    // Create the Prism script tag to inject in the DOM.
    var prismScript = document.createElement('script');
    prismScript.src = '/wp-content/themes/calvinkoepke-com/build/js/prism.min.js';
    prismScript.type = 'text/javascript';
    
    
    // Load the script only if there is any pre/code tags,
    // and only after the window has finished loading to avoid blocking any rendering.
    if (code !== null) {
    	window.addEventListener('load', function() { document.body.appendChild(prismScript); });
    }

    });

Using this strategy allows me to only fetch the Prism.js script if the page requires it, and only execute that script after everything else has finished rendering; essentially loading JavaScript dynamically. That's a win!

4. Optimized Hosting

This may be biased, but quite literally StudioPress Sites is one of the fastest WordPress managed hosting around according to WebMatros. I won't get into a huge pitch (but seriously, it's worth considering), but a couple of the benefits include PHP7 and HTTP/2 support — both of which make a huge difference in load time for your website.

CSS Grid is Powerful and Easy

The other main focus of this theme was that I wanted most of the scaffolding to be done via CSS Grid. I know, some of you are screaming at me already for using CSS Grid to create some basic columns. First off, relax. Web development is fun and so is CSS Grid. ;-) Second off, you are likely correct. Generally, using CSS Grid is better utilized for two-axis layouts. Since Grid gives you access to both X and Y grids, it's useful for creating horizontal as well as vertical rhythm. Another benefit of CSS Grid is that it's actually has pretty performant rendering compared to alternatives like float and flexbox. There are some small caveats to that, but generally it works very well. With that being said, I don't use a vertical grid anywhere in the entire theme. The reason is mostly because I couldn't find a reason to, and the other reason is that I'm still learning how to use Grid. This theme was a way to get my feet wet and see what Grid could do. So far, it's pretty rad. If you aren't seeing a grid layout, you should see a notice on the top of the screen. An easy way to get Grid is to update your browser to the latest version (all new browsers except for Opera, I think, have shipped Grid support). Still, I would love some feedback on my implementation of Grid. It's very basic, but I'm sure there are areas that I could improve on and/or use more appropriately. To see my implementation of Grid, check out the source code. I'd love to hear your feedback!

Starter Theme is the Base

I know, this post is getting long. The technicalities of the theme have already been stated. But I wanted to draw attention to a fact that may not be obvious: I am using Starter Theme as the base for this theme. The main difference from v1.0.0 of this theme? I am back to using SCSS as my primary CSS preprocessing language. Before, as you might recall, I was using PostCSS exclusively. The reason I went back to SCSS was mainly because, besides some annoying syntax highlighting issues when using next-gen syntax, SCSS is much more powerful in regards to processing and function use. And, I thought it appropriate to use the starter theme I built so that it gets better over time.

Thoughts?

With that, I'd love to hear what you think of v2 of this theme! Could I have done something better? Any suggestions? Let me know in the comments or on Twitter!