24 Apr 2014
First update in quite a while… but worth noting this blog is now powered by Jekyll after a pretty bad run of security things with WordPress (my fault: not keeping it up to date, their fault: security holes every other day).
Good news is everything is static and Github Pages hosted now. Comments have gone to Disqus (for better or worse), and analytics stays on GA (I just upgraded their circa 2007 Urchin tracking JS). Love it when stuff starts to work.
24 Jul 2013
A friend sent this Mobify article my way with a one-liner comment: "Sprites over Data URIs?"
True to Bettridge’s law of headlines, here’s my reaction.
Their test image is a 17.6KB file. If you're serving up any files that big you've already lost (see also, our jumbo sprites on mastheads). See also the recommendation at the end of the post to "use data URIs in exactly the right way" -- which, I hope, is broadly how we've been using them.
This isn't to completely disregard these results, but I would like to see it run with better test data (images in the 500 byte - 4KB range, say) to reflect actual best practice usage. Again, if you're using images as large as they are, there are probably ample opportunities to make easier micro-optimisations, which is what this whole debate is about.
That said, there are plenty of other problems with this article.
The penalty of data URIs for older phones is severe - on Android 2.2 materialization of five 17.8kB images took almost 2 seconds in the data URI condition!
Note how Android 2.2 is a complete outlier in the original chart and subsequent observations -- it's not supported by us, and comprises >0.5% of m-site traffic (source: GA, last 30 days). It's a red herring that would be better off excluded for honest charting -- especially given the author's own data reflects ours -- see his own RUM chart distribution for evidence.
There's also a methodology problem in that this is dealing with inlined src attributes on elements, which introduces additional DOM performance and possibly reflow considerations assuming these are visibly attached that you wouldn't experience with background images in CSS. Completely agree that it's harder to measure the nonexistent 'load' event of CSS background images, but that isn't a defense for the disingenuous finding that this equally impacts all inlined images. (Though the high CPU assumption seems sound enough.)
Here are a couple of assumptions of my own:
CSS parsing is necessarily more efficient than popping elements onto an unstable DOM, unless you attach the CSS late in the load. Note how in the histogram charts image materialization starts dependably late (i.e. reliably >5ms in) -- CSS parsing has happened long before this assuming it was in the head.
CSS uses 'classes', and is therefore more efficient than creating separate DOM elements with separate attributes that need to be individually unpacked. Therefore, measuring the materialization of five images is a poor test, unless four of those were deep cloned from an original element and browsers somehow cache the unpacked binary data (poking around source code and bug reports might help ascertain this). Suspect the test didn't do this, and if not, strongly doubt that browsers would have stored a hash of the unpacked encoded data to quickly reference -- memory is too tight on mobile to bother with this.
Because of 2, multiple instances of elements (commenting icons, media type indicators, etc.?) will not incur any measurable performance hit over loading just a single element, though obviously more elements on the DOM costs something.
Even disregarding 1-3, we are splitting hairs here. It's a micro-optimisation whereby we're hoping to move events in the 10-20ms range (if you accept that a 17KB image is even a reasonable test) to the 1-5ms range. That sounds big, but consider the number of elements we are doing this with, and consider user perception of this on pages that can already take over a second to load.
Data inlining, especially with preprocessors, is about maintainable code (because sprites are the Dementors of the front-end world), repeating/large-but-small-filesize backgrounds, and the ability to pick whatever format you like should you so choose (i.e. for some very small images, GIF outperforms PNG, and for some textures, JPG outperforms PNG, and with inlining you can CHOOSE to do this!)
If this is really keeping you up at night, look into using Appcache as well, because that'll hopefully save on some network pain (assuming we're worried about that given how bullish the original post is on pipelining). I apologise in advance for the caching complexity and curly support requests it creates!
Still firmly of the view that there's a big place for data-inlining on the mobile web.
26 Apr 2013
We currently have a strong dependency on SSI at work and were recently offered a nicely-specc’d Xserve that was being retired for use as an in-house preview server.
I’ve got my doubts about SSI, but we have literally thousands of templates that require it for includes. It also functions in subtly different ways to PHP, and we’re not about to embark on any bulk conversions of our front-end templates into haml, jade, or whatever else is in vogue – the legacy cost is too great.
Apologia out of the way, we are using Mountain Lion’s in-built Apache 2.2 server after a trigger-happy rm -rf on my part killed a painstakingly crafted homebrew version implemented by a colleague.
If you are using the in-built server, you are using virtual hosts.
This simple truth is not well documented online, so if you are spending time in
/etc/apache2/httpd.conf you will not succeed. The default port 80 (non-SSL) vhost file is at
Enabling SSI parsing
There’s ample info online about enabling mod_include, but what isn’t mentioned is that you need a handler specified in the virtualhost config.
AddHandler server-parsed .html is all it takes, but this won’t necessarily have effect within your directive unless you tell it to.
An age old tale of computers doing exactly what you tell them. And a wasted Friday afternoon!
*[SSI]: Server Side Includes
19 Apr 2012
JSON is nice to read. It’s also nice when parsers are forgiving, but here we are.
I just spent ages chasing [what I thought was] a bug using $.getJSON in IE7 that turned out to be an issue with something else entirely.
If you’re using $(el).css or .animate with JSON, make sure you’ve terminated all items correctly and don’t have any hanging commas left over:
This case sent me particularly crazy as I was also dealing with an actual JSON request in the same general vicinity that I’d validated a bunch of times and seemed perfect.
Note to self: Before you go down the whitespace and text encoding rabbithole next time, make sure you’re actually checking the right JSON!