Published in: Case Study

Site optimization case study: increasing a website's load speed by 500%

Site load speed is one of the big decided factors in whether a visitor sticks around on a website; web users want information quickly, so no matter how well-designed and intuitive your layout is, if a user is stuck watching a blank screen for more than a few seconds then their chances of just giving up and looking for a different website to serve their needs grows exponentially.

Despite its importance, for many site admins the task of getting a site running faster and smoother is daunting; there are so many factors to consider, and with much of it getting quite technical it might seem that there is little that can be done to salvage a slow site. However, you'll find that there are many common issues that can easily be overcome with the right processes. In this case study we'll highlight one of our clients' websites and show how, with some clever fixes, we successfully brought his load speed down by 500%.

The client originally contacted us as his news-focused website, http://wyspaslodowa.eu , was not running to expectations. He requested that we find out what was holding his site back and optimize it so that it could better serve its userbase. It was a lot of work, but the basic steps to achieving this impressive speed gain was down to following some clear, concise steps.

Step One: Preparing a Site Analysis

It's no use jumping straight into making changes to the website; if we were going to provide the best possible outcome it was important to make sure that we knew exactly where the most gains could be made. To help with this we took advantage of some common, popular tools to analyze the site and give us an overview of its load process, including:

  • Gtmetrix
  • Pingdom Tools
  • WebPageTest
  • Website Speed by dotcom-tools.com

Gmetrix rated the website's performance as 86% for PageSpeed and D (64%) in the YSlow text. It also provided us with some core details; the total size of the page loaded was 2.91MB, and there were 155 requests made to the server to complete the load.

Gtmetrix performance speed test
Gtmetrix performance speed test

Though the initial results were not terrible save for the overall page size, one we moved to other metrics tools things took a turn for the worst; Pingdom's test rated the site at 68/100 points, with a page size of 3.2MB loaded over 169 requests, with total loading time from Sweden sitting at 5.2 seconds.

Pingdom website speed test
Pingdom website speed test

Five seconds may not seem like a lot, but when we're talking about internet websites we really would rather keep load time under three seconds, as anything more than that will increase the risk of the visitor bouncing from the website. The web performance test conducted via WebPageTest was also discouraging, with a total load time from Frankfurt, Germany of almost 16 seconds, with a page size of 3.08MB and 160 requests made to complete the page load.

Web Page Test
Web Page Test

Dotcom-Monitor's website speed test allowed us to test the average load time using timings from tests run at 23 locations across the world and was 14.4 seconds, with a total page size of 3.6MB.

Dotcom-Monitor's website speed test
Dotcom-Monitor's website speed test

So clearly the site isn't running as fast as we would like. After these tests we've got hard data on load time, and we've also got a log of requests so we can see what items are loaded and their respective sizes, as well as the time spent on each request. This will allow us to focus our efforts efficiently to target wasteful areas.

Part Two: Host Server Examination

When optimizing a plain HTML site diagnosing the root cause of slow load times can be relatively simple (depending of course on the complexity of the site). However, in this instance the client website was based on a CMS, WordPress, which opens up many new potential issues. Poorly-optimized themes or plugins, or just too many plugins being loaded can have extremely detrimental effects on load times, so if we were going to make the improvements to load speed we wanted then it was necessary to examine the CMS closely.

Before that though, we took a look at the hosting used by the client; depending on the provider there are sometimes major benefits to be had from modifying the server configuration or even switching to a more global host. Thankfully, the hosting company in this case provides high-speed services on a web server using LiteSpeed Enterprise (a much faster solution than Apache), as well as high-speed SATA and SSD hard disk storage.

Since the website we were testing is entirely in the Polish language, its target audience is, for the most part, contained within Poland. This makes the measurements taken from far outside the country largely irrelevant; there's not going to be too many Polish speakers accessing the site from the Middle East or Asia, for example. Along with the solid hardware and software used with the server we didn't have any reservations moving straight on to exploring the CMS, rather than making any recommendations regarding the server.

Part Three: Analyzing & Optimizing WordPress

When building a website WordPress can be a godsend, allowing for rapid content generation and simple customization thanks to the multitude of themes and plugins available from the repository. However, this can be a double-edged sword; the open-source nature of the CMS means that it benefits from the input and expertise of many talented individuals who work hard on optimizing the code and adding useful features, yet since plugins and themes can be built by just about anyone, not to mention that there are literally tens of thousands of them to choose from, there's always a risk that the plugin you're using is inefficient and contributes to slow load times.

These potential issues made examining the client's WordPress installation an essential step if we were going to improve load speeds significantly. From a pure design point of view the site already looked clean and accessible, and for the most part there were few heavy graphic elements apart from a few icons. However, looks can be deceiving; where load speed is concerned it is just as often the code that can be the culprit in slowing a site down, and not just media or other elements. In this case, there were a number of plugins that contributed to the long load time, and the theme that the site uses, it's a multi-purpose theme designed for many different styles of websites, which means that it includes a lot of scripts, CSS and other code that we need to take into account.

Fixing the Plugin & Widget Problem

Upon investigation we found that there were a number of problems with the plugins being used, but the search for solution doesn't always prove fruitful; optimization can often be a balancing act between pleasing the client from a design and functionality point of view while keeping the site as light and rapid as possible, and these values may come into conflict. During this phase of our optimization process on the client site we noted and resolved where possible the following issues:

  1. The frontpage content was generated by an ACF (Advanced Custom Fields) plugin, which, after some testing, we discovered was causing a troubling two-second delay to the first byte of data being sent; this is an incredibly long period and was something that we wanted to fix straight away. However, this was where that balance between client needs and our optimization goals came into play; the client wanted to keep the layout as it fit their requirements, but disabling the ACF plugin would essentially break the front page, requiring us to rebuild its layout and functionality from scratch. It was simply too cost and time-intensive for the client, who requested that we simply leave this plugin untouched, with the hope that greater gains in other areas could overcome the issue.
  2. Another weak point in the plugins was a social media widget that was used to add things such as share buttons for Facebook and Twitter to post pages. The widget the client had chosen for this task generated a large number of requests and significantly increased the page size. For this reason, we removed the plugin entirely and built our own social sharing link icons with just a couple of lines of CSS and JavaScript code. With this implemented the number of requests was reduced by 28 and the weight of pages the icons were on dropped by half a megabyte; a huge deal in website terms.
  3. Social media is constantly in the mind of many website owners, given that it can be a powerful tool for sharing articles. Mindful of this, the client had installed a Facebook Page Plugin, which generates a promotional block for a Facebook page on the website. Though prominent promotion of social media can be helpful in building an audience, this one plugin was generating 67 requests during page load. For this reason we recommended that our client remove the plugin completely; a Facebook preview does not add any particularly attractive or functional elements to the site so its loss shouldn't be a problem. The client agreed with our assessment here, and we immediately removed the plugin.
  4. You might think that if a plugin is not being used live on the site then it doesn't matter how many you have installed, but our experience with the Awesome Weather Widget tells otherwise and drives home the importance of managing your plugins and widgets efficiently. The client did not actually use this plugin, so though it was installed and activated it hadn't been inserted into any pages. Despite this, we found that it was still loading the Open Sans font from Google Fonts automatically on every page of the site, adding more requests and time for literally zero return. Naturally, this widget was deleted entirely.
  5. Another widget, Cookie Law Banner, provided the basic functionality to ensure the website complied with European law regarding storage of cookies; essentially, the website needs to post a banner explaining what cookies are, how they can be used, and request authorization from the visitor to allow the use of cookies (either implicit or explicit consent, depending on settings). Though this functionality is a requirement for Europe-based websites, this particular plugin was quite inefficient, adding one second to the load time. We decided to replace this plugin with our own CSS and JavaScript for the same functionality but much lower load cost.
  6. We also removed two other unused plugins; Allow JavaScript and Simple-Lightbox, as the client did not use either of these plugins on the live site but they were still loading unnecessary scripts, delaying the load time by approx. 0.4 seconds.

Part Four: Code and Content

With the plugins cleaned up we could start looking at the core elements of the site; the CSS and JavaScript code that underpins the site, as well as the content of the pages and posts; in these places the text content is not (usually) a problem, but with media playing a key part of most websites it can be an important area for optimization.

Optimizing the CSS and JavaScript Code

One of the first things we noticed that was having quite a severe effect on the load time was the number of Google Fonts being loaded. While the site itself only used two, which is reasonable amount to work with for most sites, there were an additional 4 Google Fonts being loaded on the site, whether from plugins that demanded a particular font (as noted in the widget section above) or from fonts that were previously used on the site, but the content has since been removed. We also discovered several scripts that were loaded by the theme to provide some specific features that were not in use on the client side, so they could be safely removed without issue.

To optimize the code and reduce the chances of bottlenecks in the load process affecting the visual elements of the site, we merged several CSS files into one to reduce the number of requests needed to load the site and moved the non-critical ones (such as CSS files that don't directly affect the viewport visible when the site first loads, for example), along with scripts, to the footer of the site. With non-critical scripts and CSS in the footer they will be loaded last, whereas files that are imperative for the layout and styling that a reader needs to be able to start reading the site comfortably will be loaded as normal in the header. This has the effect of ensuring that the first few moments of loading are spent giving visitors something to work with on the page, instead of leaving them at a blank page until all elements are loaded.

One of the issues running a site via a CMS can cause is that particular plugins or resources will be loaded on every page when they are only needed on specific pages. On our client's site elements that appeared on only one of two pages such as a ticket purchasing system, Google map, contact form and post-specific ratings were still loaded on every page. To combat this, we moved the relevant scripts and CSS files so that they were loaded only on the pages where their respective functions were put to use, avoiding pointless additional files being downloaded on every page. We also took this opportunity to disable another plugin, JQuery Updated, as it loaded redundant Query libraries.

Reduce Image Weight

You'd be hard-pressed to find a website that doesn't use some kind of images nowadays, but it's surprising how many people are unfamiliar with just how weighty these elements can be if we're not careful. With many images being taken with cell phones that have relatively-powerful cameras but aren't particularly good with compression, it's quite common that images are simply taken and uploaded, with no attempt made to reduce the images impact on the total page weight.

On our client site, for example, we found that images made up an incredible 41% of the total weight of the website; the images just on the frontpage exceeded 1.1MB in size, and the rest of the site's images (mostly images used in blog posts on the site) combined to add a total weight of 35MB to the site weight. Here's where the right tool can make all the difference in the world; by compressing the images to weigh as little as possible without making any sacrifices with regards to the image resolution and quality we were able to reduce the size of the images massively, with the renewed frontpage images weighing just 378KB, with the total site now being only 13.6MB in size!

Radical Image optimization and compression
Radical Images optimization & compression

Since we were already optimizing images we also took this time to optimize the graphic elements that were provided and used by the installed WordPress theme, reducing their weight by 69% for a saving of 64KB.

Part Five: The Tricks of the Trade

So far in this article the solutions discussed have always been logical; we see an particular issue such as a specific element causing a large delay in the load process, and we fix it, whether by removing the element entirely or creating/implementing a more efficient alternative. Sometimes though, some of the most effective changes that can be made are general to every website, and even an analysis isn't needed to know that applying these particular solutions will provide a net benefit for the site.

Utilizing Browser Caching & GZip Compression

Every time your browser loads a website, it sends a request to the website's server and starts grabbing all the elements it needs to build the site for you to see and use; HTML for the content, CSS for the styling, JavaScript for the functions, images for the blog posts etc...This makes sense the first time around, but what if the visitor starts dropping by the site regularly?

Imagine the scenario; you get a new job, but it requires that you travel to another city away from home every week. Now what's more efficient; carrying a full suitcase of luggage with you every single time you make the trip, or taking some essentials with you the first time and leaving them there, so that when you return next week you don't have to carry as much?

Obviously, the second option is the more efficient; it makes a lot more sense to limit the load that's being carried on every trip. Browser Caching is like the digital equivalent of this solution; there are some elements of a website that rarely change such as logos, or elements that remain the same on multiple pages such as sidebars. Using the browser cache, you can tell browsers that load your site to store these elements locally instead of re-downloading them every time a new page is loaded; this way, many of the files are ready to go as soon as the page starts to load. If we're talking about some fairly heavy element like a complex script or CSS file, then some huge savings are possible.

On our client site we set an expiry date for particular file types using the htaccess file:


ExpiresActive on ExpiresDefault "access plus 1 month"
ExpiresByType text/cache-manifest "access plus 0 seconds"
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
...
                         

Basically, this kind of code tells the browser something like "All images should be stored for one week, all logos should be stored for 1 year etc..."; then the browser knows what files to store and how long to store them for before they are redownloaded. Setting expiry dates on particular elements allows for more refined control of the user experience, and with the right settings it can feel like a site is loading instantly.

For an extra burst of speed we also installed the useful WP Super Cache plugin; this is a very fast cache engine for WordPress that can be a real boon for site speed. Usually, when a user visits a particular page, a request is sent to the server for the page data. The webserver then needs to process the relatively-inefficient PHP code that creates the page content before it can be served to the browser. The WP Super Cache plugin gets around this little delay by pre-preparing a static HTML document from the dynamic code of the post/page which can then be sent immediately on request from a browser, which allows for much faster processing of the site content. The plugin also boasts some pretty advanced options for the tech-savvy user, including CDN support.

Another one of the core checks we performed here was to ensure that the site was taking advantage of GZip compression, which reduces the time needed by the webserver to deliver key files to the browser by compressing them to a smaller size, potentially providing a significant speed boost. In this case, the client website appeared to be already running GZip, so no further action was needed.

Flushing the HTML Code

The process that a browser follows to build a webpage is not as straightforward as it seems; there are so many elements, checks and other things to take into account for a smooth transition. One of the peculiarities of the process is the page generation phase; this is the time when the webserver has received a request for a page, but it's still preparing the first of the content to be sent to the browser. The webserver won't serve up any generated content before it is complete, but by adding the PHP flush() function between the head and body of the client website we are able to force the webserver to immediately deliver the crucial content defined in the head section, such as stylesheet download requests and partially-generated HTML code, to the browser while the rest of the page is being generated, speeding up that crucial first few seconds that a visitor is on the site.

The function we added between the head and body of the site was very simple:

<?php flush(); ?>

Bonus WordPress Actions

Just like how there are particular optimizations that are useful regardless of the make-up of a site, there are some habits that are simply good practice for keeping a WordPress-based website running fast. They do not have as big an impact as the main changes we've covered so far in this article, but that doesn't mean that their benefits should be dismissed; sometimes a large number of small gains is just as effective as one big gain. The processes we applied to the client site were:

  • Database optimization
  • Disabled pingbacks and trackbacks
  • Removed Emoji icons
  • Minified HTML, CSS and JS files using the Autooptimize plugin

This rounded off our optimization process for the site.

Summary

The optimization process was fairly long-winded and required a lot of hard work to apply, but the results clearly demonstrate the importance of optimizing your site; once all our proposed solutions were applied the customer's website was running close to 500% faster than before compared to our initial tests. This isn't even the best it could hope to reach; since we were not able to disable the ACF component as its functionality was required by the site frontpage we ended up with an average load time of approx. 3 seconds; were we able to disable the plugin this could easily have been reduced to under 2 seconds.

The renewed results from our analytical tools shows the extent of the improvement, with PageSpeed results sitting pretty at 94, YSlow at 91, and Pingdom scoring the site as 98; an increase of 30 points.

The final result of the website optimization process
The final result of the website optimization process.

The real benefit of this process though is not visible in the tests; it's the higher visitor satisfaction rate that comes with a fast, easily-accessible website. With the boost in load speed, the client can expect higher rates of returning visitors and reduced bounce-rates. As a final aside, we didn't just make optimization changes to the site; we also applied our knowledge to provide lots of small customizations to make the site even more appealing visually; you'd be surprised what a fresh look can do when combined with a faster page load speed!