Magento 1: Improve Website Page Load Time through External Resource Cleanup

Any user of Magento knows it’s not the world’s fastest platform.  Despite that, it’s a great platform and with a little tender loving care, you can really make some strides in cleaning up it’s performance.

I recently did a cleanup project on a Magento site.  I’m sure there is more that could be done, but this was the start.  When it was all said and done, I had reduced the homepages file size by about 33%, reduced the number of server requests, and shaved off between 1/2 a second and 1 1/2 seconds for page load time (depending on the page).  I’m not promising that all Magento sites can see these same results, but my assumption is that like most site, there is code inflation that can be gone through.

Decreased page load time will increase user experience and increase profits.
This page timings shows the actual change I’ve experienced from my Magento code cleanup. This data represents 3 weeks after the change and 3 weeks prior. The first set of numbers in the Vs comparisons is the current time period. You can see all of the page speed metrics have decreased, with an average of a 1/2 second decrease across the entire site.
Decrease the page load times on your Magento category pages
This is one of the primary category pages on the site – the top numbers being the current period and the bottom numbers being the prior 3 weeks (use the same headings as the above image). That’s a 1 second gain on our most popular category page!

I should note – all of this work was done on the frontend code.  I’m aware of several efficiency gains I could do on our site for the server-side code that could help the server processing time, but that’s another project I’ll be getting into another day…

And one more note – while this post is directed towards Magento users, the principles laid out here will apply to most any website. 

Code Bloat – Where does it come from?

Magento code bloat will slow down your website
Clean up your Magento frontend code base to reduce code bloat, decrease page load times, and increase usability and conversions.

First off, Magento was designed to work for every scenario.  For that reason, it has a lot of features – so many that you aren’t using most of them.  For this reason, rather than adding on functionality when you need it, it’s typically already there waiting for you.  While this is nice, that means you are serving to your visitors code that they will never use on that visit.  So why are we doing this?

Add on top of Magento’s base layer that fancy theme you are using.  That theme developer had great ideas in mind and thus programmed a certain way.  And your team made the decision to not use that feature – but I’m guessing there are still remnants of that code…

And don’t forget that extension that you installed – and then decided to not use anymore but didn’t remove.  Or that other extension that you are using but have modified the code to make it work how you wanted it to work.

All of these actions are necessary and I’m not criticizing you for doing them – we all do.  But you need to keep in mind what the trickle down effects of these actions can be at times.  While your site works, it’s not optimized.

Impacts of Code Bloat

There are many.  The first one that tends to hit people quickly is the pocket book impact.  Serving extra code to your customers that they don’t need means you are using more bandwidth than needed – you are sending more data than is really needed to your customers.  And you are charged for every bit of data you send.  So if you send less data, you spend less on your servers bandwidth charges.

But the extra bandwidth problem hits your pocket book again actually.  Sending data takes time, and customers don’t like you wasting their time.  So if your site loads slow (because you are sending too much data) they are likely to leave your site and go shop elsewhere.  I know that sounds funny, but there are countless studies that show this is the case.  I don’t conduct studies, so I’ll take their word for it.  And despite us being in the high-speed internet era, you have to keep in mind we are also in the mobile revolution, and sadly mobile phones have a mixed result in internet connection speeds.  For that reason, the leaner the site, the quicker it loads on ALL platforms, and the more money you will make.

Another impact (which since we are in ecommerce goes back to the pocketbook) is Search Engine Optimization – you know, that acronym we all hate: SEO.  On April 21st, 2015 Google rolled out an algorithm update nicknamed Mobilegedon – if your site isn’t mobile friendly you won’t rank as well on mobile searches.  Now in fairness, that update didn’t look too closely at speed (rather more responsive design or dedicated m. site layouts), but prior to that they did factor site speed into ranking factors.  In addition to that, they analyze every character on your website and use it for determining how to rank your site and for what searches your pages are relevant for.

Bottom line, this is one of those out of sight out of mind stories.  You look at your site and it works.  Your analytics say you are getting traffic and money.  But give your developer a week to dig into what is on the site that isn’t needed, do some cleanup, and give it a bit of time.  I’m confident that you’ll start to see some shifts in your analytics – organic visitors will rise, time on site will go up, bounce rate goes down, and the sales and revenue line keeps growing.  And we all know that’s exactly why we are using Magento – is to watch our sales grow.

Reducing Code Bloat

As you go through your code to see where you can make some gains, there are two things that you should keep in mind regarding what will slow down a website in terms of frontend code.

  1. The number of server requests made (files transferred from the server to the browser)
  2. The size of the files (HTML code included) – the larger the size the more time it will take to transfer it all

Reduce Server Requests

Every server request requires several steps between the browser and the server.  A request is sent, the server responds.  The browser responds back, and then packets start sending from the server.  Once the browser receives all of the packets, they get reassembled by the browser and that file has been transferred and the server request is complete.  If that isn’t enough steps, let’s also factor in the time it takes for the server to respond, the physical network transmission time, the possibility that a router/path between the browser and server could go down or get busy, etc.  Bottom line – a server request is taxing.  And larger sites can easily get into the hundreds of requests per page!  (Ever notice the Google homepage loads rather quickly?  I just checked on a day with a fancy Google Doodle – 28 requests.)  The fewer the requests the better performance your site will return to you and your visitors.

Is this JS library Needed?

Javascript files are very useful and at times crucially necessary.  Other times they are added for convenience, and many times you don’t know why they are there.  This can make it tricky to start removing files, because you now need to determine if anything broke in the process.

I started by looking at the list of Javascript files and libraries that were being loaded.  There were a lot.  The first thing that stood out to me was that we were loading 4 jQuery based image gallery slide show libraries on every page.  As I dug a bit deeper, one was used on only one page of the site.  Another on two pages. A third was used on most pages, and the fourth was never used.  So here’s a good staring point.  I ended up leaving two of them in place because they each had some unique features from each-other that we do use.  But that was a good start.

Another javascript library that I found was being loaded too often was the Facebook SDK.  As it turns out, this site only need the SDK for the product detail pages – it was being loaded on every page of the site.  I am now using the Magento XML layout files to load this script only on the product pages.

In my mind the jQuery core library is essential on nearly all sites.  I know some can argue that Zepto is smaller, and Prototype is already part of Magento (in the 1. series at least – it sounds like it won’t be in future 2. releases), but I’m a jQuery guy through and through.  But I’m not mentioning this to enter a JS library war.  What I am getting to is that many people pair up jQuery UI with jQuery.  jQuery UI offers some great tools for a site and is handy, but also can cause code bloat.  Most sites don’t use all of the features offered by jQuery UI – yet the quick and easy thing to do is install the full library.  They do offer custom builds for specific features on the jQuery UI site.   I’d suggest using a custom build of jQuery UI with only the necessary features.

Magento also comes with many default libraries – not all of which are used.  I didn’t touch too many of these, but one that did stand out to me was calendar.js – it’s being loaded by default on every pages I believe and we never once use it on our site.

Look for code that was added by your theme that you may not be using.  The theme we started our site with had lots of features – half of which we either don’t use or modified to the point that the library or script blocks they loaded isn’t needed anymore.  So here again, no sense in loading that to our visitors.

Next, go through your custom javascript code.  We load a javascript file with some default functions that are used on most every page.  In there I found a few functions that we no longer use.  One example is a whole class that was re-written in PHP and all of this was pulled out of Javascript.  Yet the code was still loading to our visitors – on every page…

Also look through your page body as well, looking for javascript blocks.  Nearly every time it’s more efficient to put javascript in an external file than it is to put it in the body of a page.  The benefit of using an external file is that the code block only has to load to the browser once regardless of how many pageviews the visitor has – provided you have your browser caching headers set correctly.  And while this is another server request, using some file merging (see below) that impact can be nearly removed.  The other reason for removing script blocks is that they are render blocking elements as the page loads.  What that means is that the browser can’t continue to render the HTML until it figures out what to do with the Javascript.  I’m not an expert on how this works, but the Google Development team is and they discuss it in-depth in this article.

Load Javascript Asynchronously

For those of you that don’t know, external javascript files can be loaded to the browser two ways – synchronously or asynchronously.  Simply stated the difference is that synchronous files need to load one at a time where asynchronous files can be loaded simultaneously.  That said, asynchronous is typically better in terms of performance because the other files don’t have to wait until that file has been transferred.  The down side though is that your page may be dependent on having that file loaded already.  But not all Javascript files are needed for page rendering – many are used for user interaction after they have the page loaded and thus they can be transferred asynchronously.  In an ideal world, all Javascript files should be sent via asynchronous.

Loading files via async is simple really – you simply add the async attribute to your external javascript file references.

But like I mentioned earlier, Javascript files that are needed for page rendering should not be sent this way – leave the async attribute off for those files.  The best way to determine if you can load asynchronously is to add the attribute in your development environment and see how your site reacts.  If all operates as expected, then leave it.

You can learn more about how async Javasript works from Google from this article.

Merge JS and CSS files

One of the best ways to reduce server requests is to merge your CSS and Javascript files into single files.  Most Magento installs have numerous Javascript and CSS files (easily in the range of 20 files for many sites), so this is a quick and easy gain as you’ll end up with 2 – one for Javascript and one for CSS.

Keep in mind for this to work, you need to be loading your external files via Magento’s XML layout files instead of adding files directly via your template files.

Also, one thing to note is that the asynchronous settings discussed above may or may not be respected depending on the method of file merging you use.

Magento Defaults

Magento offers a feature for this by default.  Set the following two settings to Yes.

Merge javacript and CSS files in Magento.
Configure your Magento site to merge Javacript and CSS files into one cached file to reduce the number of server requests your website makes.

This stores the merged files in the standard Magento cache.  So if you make an update to either your Javascript or CSS files, you’ll need to flush the cache before your users will be served the changed files.

Fooman Speedster

Fooman Speedster is a Magento extension that was introduced to me by my Magento mentor.  Fooman Speedster merges the Javascript and CSS files like the Magento default configuration option does, as well as compresses and minifies the files and handles versioning for when your files change.  No cache flushing is needed here.  It’s a pretty slick and FREE extension.

NOTE that this will override the default Magento settings described above.

The one downside I found is that it does not handle the asynchronous Javascript attribute.  However, it didn’t take much effort for me to modify the extension to allow that by adding async as a new type option.

Image Sprites

Another great way to reduce server requests is to reduce the number of images served.  I’m not saying you should remove images from your site (not yet at least), but to instead merge your images into a sprite.  For those of you that don’t know what a sprite is (don’t worry, I was confused as heck the first time I heard the term too), it’s simple really.  You create one image file that holds multiple images in it.  Then, use CSS to position this sprite (the multi-image image) to only show the portion of the image you want to show.  Typically this is used for design elements, backgrounds, smaller logos, badges, icons, rating stars, etc. on your site.  The goal is to still not create a massive image in terms of file size (I’d suggest 60kb or less) but by merging many of these small files you’ll reduce the overhead of multiple server requests.  I’ll typically use a transparent background on my sprites, saved as a PNG-24 with transparent background (in Photoshop use the Save for Web option).

To add a real quick CSS sprite lesson, you’ll set the image URL as the background image for an element (a <div>, <span>, etc.).  Then turn off background repeating, set the dimensions of your element with the height and width settings, and lastly position your background image to the coordinates of where your desired image is located – it is normal for this to be negative numbers.  I’ll typically create two classes for this – one for the defaults that get set on every sprite and one for the specific image I’m trying to display.

Icon Fonts

There are many times you can get by showing images without showing images.  And yes, that was intended to be confusing.  ha!  Several icon fonts are available for free in the marketplace and are GREAT ways to easily load multiple image-looking icons onto your site without the overhead of the image files.  You load one small font file and use it across your site as you’d like.  Most icon fonts are chock full of common logos, design elements, navigation icons, etc.  They are worth a look if you’ve never thought of using one.  The idea here in terms of code cleanup is to replace some of your images with an icon font – thus reducing overall site file transfer size and server requests.

Use icon fonts to replace multiple images
Most icon font libraries are so large that you can always find what you need for your design elements, most common 3rd party logos, navigation icons, and more. And since they are a font set, the file size and transfer is so minimally taxing to your visitors you will enhance both your design and site load time in one small change!

Icon fonts can be colorized like any font (so only one color) and most of them have built in options to be able to stack multiple on top of each-other (you could use a different color for each in this case), rotate them, etc.

If I had to say one negative about icon fonts it’s that SO many sites are using them that they are not the element that will make your site unique from others.  Despite that, they are so handy for many of the basics that I have a hard time not using them.  And to counteract my prior statement, it’s not the icons and logos on a site that make it unique – it’s your content and design that will make you stand out.

Here are some of the popular icon font sets.  But a Google search can help you find others if you’d like.

Reduce File Size

Files are what make your webpage – the HTML and Javascript code paired with CSS and images.  So there’s no way around needing to send some files.  But the trick here is ensuring that those files are as optimized as can be, thus reducing the size of them and in turn transferring ONLY what is needed.

There are a ton of articles about how to analyze your site to see what features your users don’t use and thus could be removed.  That process will of course help in this task, but that’s not I’m going to cover here.  Instead, I’m going to highlight how to identify where there is opportunity to simply optimize what you have.

Unnecessary or Hidden code blocks

Code that is never used is taxing for many reasons – it’s more for the server to process, it’s extra code that needs to be transferred across the network connection, it uses unnecessary memory on the visitors device, and can have negative SEO implications.  Finding this code isn’t always obvious for obvious reasons – it’s hidden.  But I feel it’s worth taking a few minutes to look through the source code of your pages and see what you can find.  You might be surprised.  You know what the page should look like, so you should know what the code should look like as well.  If you see text or code that you’ve never seen before, you may have struck something worth digging deeper into.

An example of this, and this is no joke, but a site I work with has ranked really well and gained high levels of traffic for years from Google for the keyword asfasdf.  We all know that comes from keyboard mashing, but the sad reality is that this was hidden in the code someplace that the customer didn’t see.  But Google did.  And that means we became one of the top ranking sites for Googlers who mash their keyboards…

Another example was a hidden code block that was loading for every product on a category page that was never used.  So this small block was loading 24 times (default number of products on the category page).  It was intended to display during an AJAX call for adding a product to the cart.  But we re-wrote how this functionality works and now just have one block that is generated via Javascript on demand as opposed to show/hide pre-loaded HTML.  So not only were my category pages full of hidden text, the text said “Updating shopping bag”.  We don’t use the term “shopping bag” on our site, and the grammar could have been better…

One last example that I’ve seen with another site, was excessive white space.  I know, that sounds funny, but here me out here.  This category page was showing 100 products by default and thus was a rather large page to begin with.  But the page also had over 7,000 blank lines.  If you do the math, that’s around 13kb of nothing.  Literally.  Now to put that in perspective, a 3G cellphone connection should transfer at a rate around 400kb per second, so this 13kb of white space would take about .04 of a second to transfer.  But the other side of the coin is that our gold standard is less than 2 seconds for a page to load.  In this example, 2% of the target 2 second transfer time is spent sending nothing.  Another way to look at it, is that many small images, sprites, etc. are around 13kb – you could send that instead of 7,000 blank lines!

Minification

The concept of minification is simple – reduce anything that is unnecessary and thus make a mini version of your files.  Many website platforms offer this as a feature, and most Javascript libraries come as a minified file (or are offered as an option).  So use any and all options where available.

Minifying your code means all line breaks, spacing, and comments are stripped out.  As an example, a CSS file that has 2,000 lines can be merged into one long line.  It’s horrendous to read as a human, but it makes no difference to a computer or web browser.  That said, it typically makes sense to turn minification on for your production servers, but for your development server you typically don’t want to minify your code.

Fooman Speedster mentioned above does some basic minification – it removes comments but not line breaks.  I may explore the extension store in the near future to see if there is another extension or way to modify Fooman Speedster to further optimize my minification.  I believe the default Magento CSS and JS merging also does minification.

Gzip Compression

I’m not an expert here, but how I understand Gzip is basically the same way that a zip file on your computer works.  You take a file, you compress it using a zip compression method, and then later the file is unzipped.

In the case of Gzip and a website, the web server it self does the Gzip compression – not Magento.  So this is set in your .htaccess file or nginx configuration.  The compressed files then get sent to the visitor, and the web browser will uncompress the files and render the page.

Before you go modifying server level files however, first check to see if it is already working on your webserver using this tool – Check Gzip Compression.

This is all a very simplified discussion of the topic, but the point is that you should be using it, it’s not terribly hard to setup, and it will make your site faster.  It’s that simple.

Image Compression

Image compression is more of an art than a hard set rule to follow.  Point is this one isn’t as easy, but can result in huge gains.  There are some common practices that can be put in place, and then some programatic methods as well.

The first common practice to follow is to not use images larger than are necessary.  In other words, if your site design shows the image as 300px by 300px, then don’t use a 600px by 600px image and let the browser scale it down – you are loading too large of an image.  Pretty straight forward.

Another common practice is to use the format that best suits your image and needs.  Example: a .jpg image will never support transparency, however a .gif or .png will.  Now I’m not a fan of .gif files – they were a good format in their day but their time has come and I don’t see a use for them anymore.  That said, if you need a transparent image, use a .png.  If not, use a .jpg.  Why?  95% of the time a .jpg will result in a smaller file size than a .png.  And if you haven’t read the rest of this post, smaller file sizes win every time in terms of website transfer times.

The last common practice is to ensure you are compressing your images as much as you can without sacrificing image quality.  If you use Adobe Photoshop (and I’m not sure why you wouldn’t…  well it is spendy, but it’s also amazing!) use the File -> Save for Web option.  Here you can see multiple compression schemes at once.  Play with the settings a bit – typically just adjusting the Quality on your .jpg outputs is enough to find the sweet spot.  As a rule of thumb though, 65 to 75 is a safe bet.  What this is doing is telling the photo editor that you are willing to sacrifice some quality for a reduce file size.  Notice in the bottom left corner of each preview pane the output file size.  Find the lowest number while still keeping the best quality.

So those are the easy ways to improve your site around images.  But there is more that can be done on the server, but to be honest I’ve not done this with Magento at this time, so I’ll talk more in theory than practice here.  But lets think through a scenario.  You have a responsive site, and you have an image that spans the width of your homepage, so let’s say that’s 900px wide for example.  That’s great for a desktop visitor that views your site via a home ethernet connection.  Now a visitor views your homepage on their mobile device on a 3G connection, and this mobile device has a width of 600px.  Technically speaking you are serving that visitor an image that is 1/3 larger than it needs to be.  Given that this visitor is on a slower connection, this does make a significant difference.

So that’s the problem – how to best solve it is another task however.  There are a few approaches that I’m aware of as listed below.  The truth behind this though, is that at the time of writing this there still isn’t a 100% best method to implement dynamic or adaptive image serving because there isn’t yet a completed spec for it, thus the browsers don’t know how to universally handle it.  There is a Responsive Images Community Group that has more up to date information about this topic.

HTML Elements

  • srcset
    • http://caniuse.com/#feat=srcset
    • This seems to be the leading HTML option.  It is just being added to most major browsers at the time of this writing – of course IE is trailing behind like usual however.
    • In an <img> tag various sizes and image files would be specified for different media-query matches.
  • <picture> element
    • http://caniuse.com/#feat=picture
    • This is the second leading HTML option, but doesn’t have as large of browser support at this time.
    • The <picture> element is a new element that was introduced to the HTML specification.  Different sources are defined within the <picture> element.
  • image-set
    • http://caniuse.com/#feat=css-image-set
    • This is a CSS approach to implementing multiple images based on the pixel ratio of a device.  Note though that this applies to background images, not an <img> element.
    • This method is something that Apple has been pushing, and since they are the the leading maker of a deeper pixel ration display (Retina displays), the lack of IE and FireFox support at the time of writing this isn’t the end of the world as those users would probably never see this.

Plugin Options

  • Adaptive Images
    • http://adaptive-images.com/
    • This seems to be the leading current best method for implementing adaptive image requests.  It is cookie based and requires minimal coding efforts.
    • Works with Apache or nginx.
  • squeezr
    • http://squeezr.it/
    • Another adaptive image solution.
  • Only works with Apache.

Measuring Success

If you can’t (and don’t) measure your success or changes, did the code change?  Ok, that was my bad attempt to modify the “If a tree falls and no one is around” brain teaser.  But seriously, why would you not check if anything changed?  I suggest running some tests before hand

Google Analytics

Reporting

Google Analytics might be the best tool here because even if you forget to do some benchmarking before you implement your changes, it’ll have data for you.  I records page load times for every page hit on your site, so you can get a good view of the before and after timings.

You can find the reoprt in your Google Analytics acount under: Behavior -> Site Speed -> Page Timings.  I personally don’t like the default report that loads, so I’ll then choose DOM Timings at the top and change the report to the Data layout (the left icon next to the advanced search option around mid page on the right).  The Avg. Page Load Time column will show you how long it’s taking a user to load each of your pages.

Analysis Tool

Google Analytics also offers an analysis tool that will show you areas of opportunity to improve your page speed.  This can be found at: Behavior -> Site Speed -> Speed Suggestions.  This is displayed on a page by page basis, so you may see a lot of similarities across most pages for the common issues that would need to be addressed.  Click on the link under the Page Speed Suggestions column for a page you want to learn more on.

You’ll notice each page is given a score out of 100.  One thing to keep in mind is that Google has created their own paradoxical anomaly(?).  You’ll notice they suggest you make changes to the browser caching time on your Google Analytics scripts.  But since those scripts are served from Google’s servers, you do not have control over this, thus it’s an impossible thing to fix.  Ok, it’s not impossible…  Here is one idea on how to use GA scripts and still pass the browser caching test from Google.  In my opinion, the potential gains are not worth my effort at this time.  But some day I might get around to implementing this.  But my point here is that don’t fret if you can’t make the perfect 100% score – I don’t honestly think that many sites will ever reach an 85.

Pingdom

Pingdom offers a great free site speed testing tool.  http://tools.pingdom.com/fpt/  I suggest running this before you push your updates and save the report.  Then run again after you’ve pushed your changes (and given the server a chance to rebuild it’s caches).

Pingdom gives your site a score (not a direct match to the Google Analytics score), as well as shows you how many requests your page makes, page load time, and download size.  Also, a nice waterfall is displayed so you can see what elements are taking the longest to load.

Website Pulse

http://www.websitepulse.com/

This is a nice service that will monitor your site daily from multiple locations across the globe.  They offer a free 30 day trial, so you can set it up a few weeks before launch so you can see a nice before and after comparison.  Nice tool with plenty of info returned – similar to Pingdom but runs daily and from multiple locations.

Browser Developer Tools Network Panel

Your developer panel that comes with your browser can give you many of these same insights for your local machine.  The Network panel shows a waterfall of the transfer times, how many requests and file size transferred.  Note that you’ll need to hit the record button on the panel and then reload the page to get a full picture.  Also note that if your browser is caching files, the transfer times and requests could be skewed from that of a new visitor.  But clearing your cache (or setting your developer tools to not allow browser caching) is a way to combat this.  But again, this is testing from one location and so it’s good for benchmarking against yourself.

Use your web browser to understand page speed.
Use the web browser developer tools to understand your page speed, files, and number of server requests. The network panel is chock-full of information including a waterfall graph.

Final Words

Some may argue that with proper caching many of these steps might be unnecessary – once the browser has loaded the files once they can load locally and reduce the transfer time.  Technically speaking there is some truth to that – for all page views of each visitor beyond their first – if they make it there.  Also, a web browser functions so much smoother for a smaller page – a smaller page really does make a noticeable difference to the user.  So do your users and your bandwidth costs a favor and clean up your code!  Please do your part in making the internet a safe place.

But don’t forget a basic principle – for every action there is a reaction.  Reducing code has it’s benefits, but can also have it’s problems as well in that you may have broken functionality or removed too much.  While you are cleaning up code, test often, test everything, and test in ways that you’ve never tested before – think like your customers, not like your habits.  At the end of the day, if this process is done correctly, the reaction to the action is improved site speed and profits.