E5: Speed Optimizations
- --Pages are nearly twice as fast, and the ‘feel’ of the site is 3X where it was.
- --If you notice certain pages not updating, what comes next? Just bust-a-cache. http://doxxx.com/editors/sass/edit#cache
The Long Story
Dev has spent around 75% of the past two weeks focusing on our Episode 5 project for speeding up our new platform, and it’s looking like we’ve gotten some fantastic results to report. Before we started the project, we looked through our ‘Fancy Tool’ (New Relic reports if you’re interested) and pulled out some stats to see how we were performing pre-project. Over the course of about a week prior to starting, here’s what it looked like:- *Average Backend Server Time (over the entire site): 990 milliseconds
- *Average Load Time (over the entire site) in the browser: 8.18 seconds
- *Average Backend Server Time (over the entire site): 299 milliseconds
- *Average Load Time (over the entire site) in the browser: 4.51 seconds
That’s about a 66% increase in speed on the backend, and a 50% increase on the front end.
Here are some things we implemented over the course of the project and a few more details in case you’re curious about what’s changed:
The first layer we put in is a '304 Not Modified' layer. This is a high level cache for our repeat visitors. Essentially, when you hit a page on the site more than once, if this cache is working, your browser assumes that nothing has changed, and lets our app servers rest. This is implemented in tons of places throughout the site, and is easily broken by doing a 'hard refresh' (shift+refresh on windows, shift+cmd+r on mac).
This is a simple high level cache layer meant to speed up the site for our repeat users.
Layer 2 is a bit more involved. This is a lower level cache on things like the header, footer, layout, specific event data, etc.
Here are some things we implemented over the course of the project and a few more details in case you’re curious about what’s changed:
Caching Layers
We've implemented a multi-layer cache setup, and we plan to grow and refine it as we proceed to the moon. Read on for what these layers are.The first layer we put in is a '304 Not Modified' layer. This is a high level cache for our repeat visitors. Essentially, when you hit a page on the site more than once, if this cache is working, your browser assumes that nothing has changed, and lets our app servers rest. This is implemented in tons of places throughout the site, and is easily broken by doing a 'hard refresh' (shift+refresh on windows, shift+cmd+r on mac).
This cache is set to expire on two conditions:
Every person coming to the page for the first time since the cache refreshed (on venue update or at the evening switch) will see whatever they were meant to see.- --If the 'page in question' is modified - say it's an event and the event is edited and saved, or it's a venue page and it's edited and saved.
- --Every evening at switchover time (4am your time)
This is a simple high level cache layer meant to speed up the site for our repeat users.
Layer 2 is a bit more involved. This is a lower level cache on things like the header, footer, layout, specific event data, etc.
These caches are cleared automatically when a related item is edited in Admin. For example, if you add an “Update” in Admin, the header and footer cache will automatically clear, ensuring the latest posts gets out instantly.
If for whatever reason these caches are giving you grief, please try the following:
User pages were a bit harder to fix, but some SQL (database) optimization, coupled with some caching has us down to an average response time of 500ms compared to 1500 - 2000ms two weeks ago.
First priority is to display the page, then the ‘current user’ data is run and applied, and finally the brand ads / featured events / and featured venues are loaded. This means people can start viewing and interacting with the site much faster than the 4.5 seconds, while all the extra data loads faster and in the background.
Lets say a page on the site has 30 images, and they’re all linked via the same domain. Your browser will grab them 5 at a time, which means it asks for 5 images, waits till they load, then asks for 5 more and so on until they finish.
What we did was implement code that breaks the image domains (we’re using Cloudinary for our images) into a randomish set of 5 domains. This means that when the browser sees 30 images, they’re spread over 5 domains, and it can load 25 at the same time instead of 5. Faster page completion times is the result.
If for whatever reason these caches are giving you grief, please try the following:
- --'Hard' refresh the page (shift and refresh on windows).
- --Check out the brand new tab in your site's SASS editor called 'Cache Busters'. Here you can click a button and bust the cache for various parts of the site.
- --Email us!
Optimizing Specific Heavily Used Calls
According to our stats, the Featured Events, Featured Venues, and User pages (and a few others) were all being hit heavily and not performing well. We spent a few days tweaking the way these work and increasing their speed dramatically. You might have noticed last week when we pushed out the Featured Event and Featured Venue changes, everything sped up! Not only did we add cache layers (bustable via the above instructions), but we trimmed the results down by removing some of the unneeded JSON, and we made it so that your Featured Venue widget only loads one venue, when it’s needed (previously, we were loading all Featured Venues with a single call even though your user only sees one at a time).User pages were a bit harder to fix, but some SQL (database) optimization, coupled with some caching has us down to an average response time of 500ms compared to 1500 - 2000ms two weeks ago.
Updating the Load Order of the Javascript
In addition to removing and optimizing our Javascript, we tweaked the load order of all the page bits for what we think is best for user experience. Our new design relies heavily on asynchronous data loading - the core of the page loads and renders as fast as possible, then other data is loaded ‘after’ the page loads, which ensures our users see what they want to see fast, and the whole site feels more responsive. Even though our overall page load averages 4.5 seconds, users will see the page much sooner!First priority is to display the page, then the ‘current user’ data is run and applied, and finally the brand ads / featured events / and featured venues are loaded. This means people can start viewing and interacting with the site much faster than the 4.5 seconds, while all the extra data loads faster and in the background.
Optimizing Images and Ensuring Multiple CDN Loads
This is something we did on the old site but hadn’t implemented on the new site. When a browser hits a page, there is a setting - unique to each browser - that determines the amount of things it will load from a specific domain name at the same time.Lets say a page on the site has 30 images, and they’re all linked via the same domain. Your browser will grab them 5 at a time, which means it asks for 5 images, waits till they load, then asks for 5 more and so on until they finish.
What we did was implement code that breaks the image domains (we’re using Cloudinary for our images) into a randomish set of 5 domains. This means that when the browser sees 30 images, they’re spread over 5 domains, and it can load 25 at the same time instead of 5. Faster page completion times is the result.