Tuesday, May 28, 2013

Web Performance Optimization, double blink of an eye

So last time I had managed to refactor my code and make it more structured by introducing a test framework. All was good, but something bad also happened.

My site (figment engine) got slow - this was not the fault of the testing framework, or the better structure of my code, it was because I took my eye of the ball.

Performance tends to fall away on any project as soon as you stop tracking it, a bit like test coverage or trousers without a belt. Unless there is a big ugly graph its easy for it to go the way of the dodo.

Earlier the site was delivery in about ~300ms (not quite the blink of an eye!), but after reviewing my progress yesterday - disaster! it was up to 700ms, this is an eternity in computing time - and much tooooo long, I was trying to target 100ms so this is going the wrong way!

So, what did I do? I was using a CDN, and my cache headers looked good. So I fell back on my personal performance mantra - the fastest way to do something is to not do it. So in WPO this means avoiding making requests - the following:

1. Convert my background image into a data URI, using an online tool this means the CSS changes from:
    background:transparent url(../pictures/crt.png) top left repeat;
    background:transparent url(data:image/png;base64,[lots of chars]) top left repeat;
this saves an additional request at the cost of always downloading the image data.

2. Inline my CSS, using M4 I can use a simple "include(assets/styles/main.css)" in the HTML to bring the CSS into the index.html. This saves another request, again at the cost of always downloading the CSS

3. (can you guess?) Inline my JavaScript, using M4 I can use a simple "include(assets/scripts/main.js)" in the HTML to bring the JavaScript into the index.html. This saves another request, again at the cost of always downloading the JavaScript.

The impact of these three tiny changes?

Document Complete Fully Loaded

Load Time First Byte Start Render Speed Index Time Requests Bytes In Time Requests Bytes In
First View 0.205s 0.135s 0.214s 200 0.205s 1 7 KB 0.258s 2 8 KB
Repeat View 0.062s 0.000s 0.050s 100 0.062s 0 0 KB 0.062s 0 0 KB

Yep, that's right - 200ms down from 700ms - and repeat views in a crazy 62ms!. Hitting refresh on this site I can't see the redraw!

The only fly in the ointment is that this test is running from the NL vs IE as the IE load tester is too busy. So this could invalidate my results if the NL test location is next to the CDN edge location in NL.

Probably the largest improvement here is caused by making less requests, and the overhead is acceptable as my site is a single page and the HTML/CSS/JS moves in lock-step.

I'm pretty happy with this gain, there are a few things I could do:
  • compress the content with gzip
  • minify the CSS/JS
  • put in place an async loader, which would give the same performance, but allow caching of seperate JS and CSS.
I'll probably leave performance alone for a few sprints, and focus on features - but I will keep an eye on the document complete time..

No comments: