WordPress can be slow. WordPress with WooCommerce can be slower. Sure. Depending on how you build a website dictates how fast a web site’s perceived performance or how short it’s critical path can be. WordPress is not immune to this logic.
Neither is any other framework, Content Management System, or process you may have for building a website. Start with a static file, reference a couple CSS files, some JS script files, a sprinkle of images, and our static site is now slow. It all depends on how we put the pieces together, or serve the assets to our users.
Why does perceived performance or critical path even matter?
Why is being able to get our content in front of users fast—on all networks and devices—important? Perceived performance and a short critical path to our content for users is a key early step in a good user experience, and potentially sales.
For our purposes today, perceived performance is all about what a user perceives the speed of a site to be. If a person is waiting for something they want, and there is no anxiety induced by the waiting process, the speed is often perceived to be better.
Take Disneyland for example. Disneyland snakes their lines back and forth for a number of reasons. All the psychological reasons relate to why humans hate waiting in lines. For one, the riders are visually much closer to the front of the line. This perception leads the rider to have less anxiety, and thus, perceive the line to be moving faster. Picture yourself in the last traffic jam you were in. Was anxiety highest when stopped dead, or at a slow and steady crawl?
The same works with websites. In particular, when the user is on a slower network. Mobile traffic is climbing exponentially, and perceived performance is more important for a website now than it has ever been. One great way to improve perceived performance is to show the user something, then load in the non-critical stuff after. This also happens to fall in line with progressive enhancement.
— Ilya Grigorik | Google Developers
Optimizing the critical rendering path refers to prioritizing the display of content that relates to the current user action.
We want our users to have as short a path to the actual content they are looking for. When we combine fast perceived performance and a short critical path to content, we are providing a positive user experience at a very early and potentially critical point in a users journey. This is what we want to consider when we lay out our asset loading strategy.
The Magic Sauce
This hurts perceived performance, and lengthens our users critical path to content as it makes our user wait for the content to display.
WooCommerce Asset Loading
I’ve been working with an evolving WordPress asset loading strategy for a while, but only recently rolled it into a WooCommerce site. WooCommerce loads a lot of assets that hold up paint. Let’s jump right into an example of a bone stock WooCommerce site on a Good 3G connection (100ms RTT | 750kb/s) on a really quick VPS server hosted on Digital Ocean.
For the geeks, it’s an Ubuntu NGINX/PHP5-FPM spitting hot fire on a Toronto droplet. It’s tuned, and it’s fast.
Chrome dev tools are our friend here. This isn’t suppose to be definitive and scientific, I’m merely trying to illustrate some optimized ways to load assets.
Notice along the top we get our first screen shot at 2.34s. This means, our users on a Good 3G connection won’t see anything until 2.34s…on a fast server. The reason is because we have to wait for all 21 requests before the page paints. This is very bad perceived performance.
Let’s see what happens when we add in 7 items. I’ve been working on a small WooCommerce powered site for a client and am using their 7 items and images. Here is our stock WooCommerce site, with 7 items on the products listing page.
Our time to paint is up to 4.70s. Our users don’t see anything for 4.70s. That is a lifetime…even on a 3g connection.
Again, the reason is that we are waiting for 29 requests now due to the images from the products. This holds up paint even more. Keep in mind, we are on a 3G connection. On a high speed 20MB internet connection, this site paints in 800ms, and is fully loaded in under a second. It’s easy to miss this when building sites if you are on a fast connection. This is why I build all sites from the ground up with the 2G or 3G throttled speed.
It really allows me to optimize asset loading from the start. If you are always aware of it, you are building performance into your build process until it becomes second nature. Like accessibility and best practices.
Here is our Network tab of Google Chrome DevTools on a slightly optimized version of our 7 item WooCommerce store at our Regular 3G speed.
The first item of note is paint in 2.62s…much improved over our 4.7s stock site. The reason for this can be found near the bottom left of the screen shot above. Right above the console we can see 18/31 requests.
The former merely disables one JS file that WP loads, and the latter delays the loading of jQuery and all dependencies until after paint. This is known as asynchronous loading. We are still waiting on 18 requests, but that is better than 29.
If we were to asynchronously load the images, we would eliminate at least 8 more requests that are holding up paint. In fact, here is a screen shot of that WooCommerce site I’ve been building. Ignore the actual load times as it is on a simple Dreamhost shared server, but look at how many requests we have at paint.
We get paint at 1.38s, and have nearly the full styling and structure of the site at 1.87s. We only have 5 requests at this point, and 4 of them are not blocking paint. Everything else loads in asynchronously.
This is were 14kb comes from. A single trip from our host to your device can carry 14kb. If you can delivery enough HTML/CSS/JS in that 14kb, and have nothing block the browser, you can get paint after the very first packet of data comes through. There is obviously overhead, and you can see on the Dreamhost shared hosting above, the download time of even that first 14kb’s is painfully slow. With mobile networks, the Round Trip Time (RTT) is what kills perceived performance. It takes so long for each packet to negotiate the exchange between user and server, the actual speed is irrelevant when you have 29 assets blocking the browser from displaying anything.
My build process is in-depth and long winded so I’ll cut it short at a Grunt workflow that let’s me pick and choose what CSS/JS loads, when, and dependent on what. I can hand build my first 14kb like I did with MaydayDogs.com. For the WooCommerce aspect, I had to use the Defer JS plugin to async all the JS that we load through WP’s enqueue system.
This is the business. Put this site on that hot little Digital Ocean HTTP/2 VPS of mine and we would have paint in under 1.00s easily for this hotdog stand eCommerce site—on a 100ms RTT 3G network. Next level fast. By getting the user going in a usable view
This was a quick and dirty look at some terms like critical path, perceived performance, browser paint, and asynchronous. As a web developer, I think about perceived performance all the time because I believe it has a big impact on overall user experience, and recognize that mobile traffic is on the rise. Yes, networks will get faster, but humans have a funny way of saturating any kind of bandwidth we are afforded.
Starting lean, building lean, and maintaining lean means that as the network gets faster, our light and fast sites will only be delivered quicker.