How the new Rocket Apps website crushes performance metrics

The new Rocket Apps website takes advantage of some common, and not-so-common techniques to crush performance metrics.

Start Reading
Rocket Apps Blog: How the new Rocket Apps website crushes performance metrics

Fun fact: 40% of visitors will abandon your website if it takes more than three seconds to load. But that’s not all. It’s also critical the user understands your key value proposition without any ambiguity or unnecessary guff getting in the way – within those three seconds. That means your message must be up-front and centre as fast as possible.

In the context of this very website, that means the first thing a user is drawn to is this message in large type: “Niche solutions for WordPress powered by ingenuity”.

Arguably “Niche solutions for WordPress” is the only relevant part, but seeing that message will immediately reassure anyone who specifically came looking for WordPress solutions. Mission accomplished.

But no amount of clever marketing will matter if your site is slow enough that the potential customer jumps ship before they see it, and there are some things you can do to mitigate this.

Web Hosting Matters

Choosing a reliable web host is going to give you a big head start, and as with everything else in life you get what you pay for. In the past I’ve seen thoughtfully engineered sites let down by a slow web host. If you pay for a $10/month hosting package you can expect $10/month performance.

Admittedly it look me a long time to learn this lesson. The developer in me was always convinced that if I engineered enough clever trickery I would be able to make up for any hosting deficiencies. I can say for certain now, older and wiser, this can only get you so far and at the end of the day you’ll have to pay realistic money for a web host that won’t let you down.

Find a host fit for purpose. For example, this site runs on WordPress and has a WooCommerce store. After trying (and failing with) a few cheaper options I eventually ended up at WP Engine who offer specifically tuned WordPress hosting, optional proprietary WooCommerce performance features, a global content delivery network, proprietary caching and more. I pay more than I was originally comfortable with, but seeing a dramatic reduction in bounces and cart abandonments soon put me at ease.

Developing For Performance

Move Your Stylesheet

In the remainder of this article I will share a couple of particular engineering habits I’ve formed over the years in the pursuit of performance and efficiency.

If you’ve ever ran your website through any of the popular performance analysers (I test with PageSpeed Insights, GT Metrix and Yellow Lab Tools to get a good coverage of feedback) you’re no doubt familiar with the “Eliminate render blocking CSS” complaint.

Basically it means that the page can not render until the CSS has finished loading, and the bigger your CSS file the more it will delay the rendering of the page.

For reference, here’s what these three performance analysers say about this site (at time of this post), and it should be noted that Google PageSpeed Insights scores are comically inconsistent, often giving you wildly different scores even when you make absolutely no changes to your site:

The problem is that almost every WordPress plugin and theme will output render blocking CSS in the head of the document, and you rarely if ever have any control over that. And while there isn’t much you can do about 3rd party plugins, if you engineered the theme yourself (or are cool using a child-theme), this one simple change can have a dramatic impact: output the CSS at the end of the document.

Now before you get out your pitchforks, hear me out. There’s no rule that says you must place your stylesheet in the head, rather it’s just a “rule” that’s been carried forward since the olden days of web design because it made our applications “feel” more organised. With this in mind, it’s perfectly valid to output your CSS file at the end of the document, W3C will have nothing to complain about, and now your CSS won’t get in the way of the page render.

There’s one small catch: there will be a couple of seconds where the page will have a flash of un-styled content until the CSS eventually loads. This isn’t a very desirable look but luckily there’s an easy solution:

1. Add an ID called fouc to the body tag.

<body id="fouc">

2. Add this very light-weight CSS into the head:

<style type="text/css">
    #fouc::before {
        content: '';
        display: block;
        width: 100%;
        height: 100%;
        background: #2647d3 url('<?php echo get_template_directory_uri();?>/images/loading.svg') no-repeat center;
        background-size: 100px;
        position: fixed;
        top: 0;
        left: 0;
        z-index: 9999999999999999;
    }
    #fouc::after {
        content: 'Niche solutions for WordPress powered by ingenuity';
        display: block;
        width: 100%;
        text-align: center;
        font-size: 4em;
        font-weight: 600;
        height: 50px;
        position: fixed;
        top: calc(50% - 50px);
        left: 0;
        background: url(/wp-content/themes/rocket-apps-3.0/images/shape-white.svg) no-repeat center;
        background-size: 45px;
        z-index: 9999999999;
        padding: 100px 0 0 0;
        color: #fff;
    }
</style>

This CSS and referenced SVG images are practically insignificant totalling around 1k. Sweet.

3. Add this jQuery after the body tag.

jQuery( document ).ready(function() {
    jQuery('body').removeAttr('id');   
});

If you’re not using jQuery, remove the ID when the document is ready using your preferred method.

What’s going on here? The CSS in the head targets the #fouc ID on the body tag and will immediately present the main message and a loading animation (especially critical on a slower mobile data connection), like this:

The thinking is this should be enough to make the user realise that something is about to happen and in theory reduces the chances of a bounce. Note: On a fast connection the document may even load quick enough to never see this.

The jQuery will then remove the #fouc ID from the body tag when the document has actually finished loading (“in the background” for lack of a better description), revealing your fully loaded website.

Move the WooCommerce Stylesheets

Likewise, you can move the WooCommerce presentation to the end of the document. This is accomplished with a simple function that dequeues the original styles and then re-enqueues them back into the footer. In your functions.php file add this:

/* Dequeue Woo styles and re-enqueue at the end of the document */
function ra_move_woocommerce_styles_to_footer() {
    if (class_exists('WooCommerce')) {
        /* Dequeue Woo styles */
        wp_dequeue_style('woocommerce-layout');
        wp_dequeue_style('woocommerce-general');
        wp_dequeue_style('woocommerce-smallscreen');

        /* Re-enqueue at the end of the document */
        add_action('wp_footer', function() {
            wp_enqueue_style('woocommerce-layout');
            wp_enqueue_style('woocommerce-general');
            wp_enqueue_style('woocommerce-smallscreen');
        });
    }
}
add_action('wp_enqueue_scripts', 'ra_move_woocommerce_styles_to_footer', 999);

Any 3rd party styles that are enqueued can potentially be dequeued and re-enqueued in this manner.

We’re accomplishing a couple of things here. First, we’re satisfying the “Eliminate render blocking CSS” complaint made by performance analysers by moving stylesheets to the end of the document. Secondly, we’re rendering something on screen immediately without having to wait for the entire page to load, which is hopefully enough to keep the user momentarily engaged.

Optimisation by Separation of Concerns

“Separation of concerns”, also known as “divide and conquer”, is a methodology typically associated with software design where the goal is to separate your application in sections with limited (or ideally none at all) overlap. Similarly this can be applied to WordPress web development for further performance gains, and when I first learned of this concept it fundamentally changed the way I develop for web sites.

So how can this be applied to WordPress (or any other website)? It begins with accepting that the ancient old method of separating your CSS, HTML and JS into separate files is both outdated and inefficient. Again, I beg you to put away your pitchforks and hear me out.

One my my biggest gripes in traditional website development is the method of having a CSS file with the presentation of your entire website and a JS file with all your scripts included on every HTML page, regardless of which CSS or JS the loaded page actually requires. This puts the page in a situation where additional resources are being loaded (costing time and bandwidth) that it may not even need.

How can the “separation of concerns” philosophy help you be more efficient? Obviously it would be very difficult to programmatically only load the required CSS selectors or JS for any given page, but we can limit the expense with some of the aforementioned clever trickery.

If you are going to have a global JS file, make sure it only contains JS that truly is required for all pages.

If you have JS that is only required on some pages, then load only when required. As an example, the blog and product pages on this website utilise a GIF player script, and those are the only pages where they are required and so I only use it accordingly:

/* GIF player on blog and product pages. */
function ra_gif_player() { 
    if(is_singular('blog') || is_product()) {
		wp_register_script('gifplayer.min.js', get_template_directory_uri() . '/js/min/gifplayer.min.js', false, filemtime(get_template_directory() . '/js/min/gifplayer.min.js'), true);
		wp_enqueue_script('gifplayer.min.js');  
	}
}
add_action('wp_footer', 'ra_gif_player');

This will load the scripts at the end of the document only on blog or product pages, meaning all other pages are not penalised with the unnecessary additional JS expense.

Likewise with CSS, if there is some styling you need that will only ever occur on a particular page, you can load it only on the required page. I created a simple function for loading custom CSS only where needed:

/* Load custom stylsheet if it matches the page slug */
function ra_handle_the_css() { 
	global		$post;
	$post_slug	= $post->post_name;
	$filename  	= get_template_directory() . '/css/' . $post_slug . '.css';

	/* Check if css file of slug name exists and if it does, include the stylesheet for that slug. */
	if (file_exists($filename)) {
		echo '<link rel="stylesheet" id="' . $post_slug . '-css" href="' . get_template_directory_uri() . '/css/' . $post_slug . '.css" type="text/css" media="all" />';
	}
}
add_action('wp_footer', 'ra_handle_the_css');

This function checks for the existence of a CSS file based on the page slug. For example, if the /css/ directory contains a file called cool-stuff.css and the current page slug is cool-stuff then cool-stuff.css will be output at the end of the document, preventing the inefficient expense of loading cool-stuff.css on every page.

Lazy Load All Images

It goes without saying but here goes: It’s 2023, and you should be lazy loading images. Either using the baked-in solution that WordPress introduced in 5.5 or by other means.

For the uninitiated, lazy loading defers the loading of elements (images, videos etc) until they are in the viewport, and will have a meaningful performance benefit.

Critical CSS

Critical CSS, as the name suggests, loads only the required selectors (critical) to render the elements initially visible in the viewport.

If all your pages have the same or very similar initial view, you can easily implement your own CSS without relying on yet another 3rd party script. Simply figure out which selectors you need to render the initial view and output the CSS into the header before your style tag. Alternatively, there are many WordPress plugins that can dynamically inject critical CSS for you.

Controversial: Move Google Analytics and other tracking scripts to the end of the document

The reason Google, Facebook and others advise you to place their respective tracking scripts into the header is because when they execute sooner they are able to track more reliably.

While placing these scripts at the end of the document will improve the initial page loading times, you risk a situation where a user navigates to a different page before the tracking scripts get a chance to load, thereby not recording the visit and skewing your analytics.

Personally speaking I care more about the performance of the page than I care about minor analytics discrepancies, and so I am happy to move tracking scripts into the footer. That is a judgment call only you can make, of course.

Hosting Provided Solutions

Some hosts offer asset, object caching and CDN solutions. If they do, absolutely put them to use.

In Conclusion

Some of this might seem excessive or overkill, but I’ve personally always subscribed to the “Every Byte Counts” philosophy. Optimisation and efficiency really does start with understanding that every byte really does count, and if you take that seriously (which any self-respecting web developer should) then it won’t be long before you find yourself squeezing gains out of every corner of your website or application.

More Articles