2011-07-05

Optimized SVGs at gist.github.com

Lately, I've been having a lot of fun hand optimizing SVG files for size, a bit like Sam Ruby does for his blog (it is highly instructive peeking at his collection, as I think I have mentioned before).

For me, SVG has something of the magical flair I first found in HTML in the nineties, back when it was the new bleeding edge New Thing, but I argue that it's even more fun than HTML was. The W3C SVG specs are not prohibitively difficult to read, and of course you have much greater graphical freedom than structured documents can afford you (duh!).

Like Sam, I try for something presentable in a kilobyte or less (uncompressed, though modern good browsers are as happy to render SVG:s delivered with content-encoding: gzip, of course, as long as they are otherwise correct and delivered with an image/svg or image/svg+xml content-type), and to never enforce a fix width in the svg tag itself – so they just beautifully grow to any size you want them to be, with no loss of quality.

Which is the other main beauty of SVG, besides being fly-weight, standardized, widely supported and still growing broader support in all the main-stream browsers. Over the last few years, the SVG front has been progressing happily and now is very practically useful already, for at least those of us that care most about Chrome, Firefox and Opera (I get the perception that Opera's often rather exceptional lead on the SVG support front is largely or even solely the work of Erik Dahlström, but I might exaggerate a bit).

[I thought what I'd do was, I'd pretend I was one of those deaf-mutes] (<- this is text content in an inline SVG, if your browser or reader has stripped off the SVG or can't render such modernisms :-) Anyway, this weekend, I had fun turning the Laughing Man (from Ghost in the Shell: Stand Alone Complex) that @elmex vectorized at some point, into a 1000 byte version of my own, also featuring the gentle rotating text seen in the anime series (YouTube), via declarative animation (so there is no javascript involved here).

Edit: I initially missed an excellent opportunity here to plug Jeff Schiller's scour, which is an ideal first step when you start from an SVG source file. Be sure to run with -p something-large, as its defaults are being lossy about precision, which cuts needed decimals from some input files. With -p 99 you'll be on the safe side. Experiment with low single-digit numbers if you like (the current default – 5 – is often good), but make sure things are still looking right, or you may just ruin your file, rather than optimizing it for tiny foot-print. Broken images don't get extra credit for also being small!

The result is in this gist (if you install this user script, you can swap between *.svg text/plain source code image/svg rendition) or to the left, if your browser renders inline SVG:s properly in HTML content (I recommend the gist over view source, as Blogger inserts linebreak HTML tags unless I strip out all newlines first).

What surprised me, when I made this user script, is how far standards support has come in modern browsers: in order to inject the <svg> tag I create for the rendered version, I had to feed the source through DOMParser (as setting .innerHTML is lossy from treating the SVG content as text/html, not text/xml), and the few lines doing that, just magically worked in all of Chrome, Firefox 4 and Opera 11 (de-jQuery:fied, to make more sense outside of the script's context) with no special extra effort on my part:
// turn the raw SVG source string into an XML document:
svg = (new DOMParser).parseFromString(svg, 'text/xml');

// import it into an SVGSVGElement in this document:
svg = document.importNode(svg.documentElement, true);

// and insert that element somewhere in the document:
document.body.appendChild(svg);
To me, that's a rather clear sign SVG is ready for prime time now.

While github reports having no plans on serving *.svg gists with an image content-type (they don't want people using gists for image hosting, I guess, even though it's sad you can't easily preview without saving to disk or using my hack above) I still think the light-weight gist community oriented sharing is good for this kind of thing. Others happily forked the octocat SVG I similarly format converted a while ago from the github About page, and milligramme made this much spacier version.

I gather all my SVG play in a svg-cleanups repository on github, if anyone wants to get inspired the fork or follow way, and occasionally tweet about it. If you find this kind of exercise as much fun, I love hearing about it; here, on Twitter, github, or elsewhere. I believe it's good teaching and learning for the web as a whole, too. Any logos, trademarks and the like above are property of their respective owners.

2011-06-04

Draw your own Github SVGs, step by step

I SVG:ified and played a little further with the logo material from the recently published Github about page, and then tonight I figured it would be fun to visualize the elegant process by which a raw SVG image is built up, piece by piece, by rather basic building blocks. With just a little bit of javascript magic to help you, here is how you piece together your own github schwag from scratch (works like a charm in Chrome, Firefox 4, and presumably any other modern browser that can handle inline SVG images):
 


If all you see is a button and the description of each step, that just means your browser doesn't natively handle inline SVG, which of course is a bit of a shame. Another reason I was curious to try this is for seeing how inline SVG:s fare in feed readers. (Google Reader seems to fail.)

Nicer source code for the images than in the page (Blogger insisted on filling all the whitespace with html junk) in these gists: github-logo.svg, octocat.svg. gist.github.com currently doesn't serve .svg files as image/svg, so you'll have to save them locally first to see them rendered.

Source code for the step-by-step drawing is in this gist; MIT licensed, if you want to fork away, adopt, adapt or whatnot. Have fun! I did. :-)

2011-05-29

Add-on hosting: Mozilla vs Google vs Opera

I habitually develop browser user scripts to stream-line things for myself (and others) on the web – and a half random scattering of them tends to end up proper add-ons, when I think the benefit of them being easy to find, install and reuse by others merits the added work for myself of packaging them and submitting them to an add-ons gallery.

This happens rarely enough for me to forget some details of the process (yet often enough to be annoying), hence this post to document salient parts of it, applaud parts of where hosts worked things out really well, and note where there are holes to patch up. (I don't cover Safari since I have not made any Safari add-ons.)




Firefox add-ons: addons.mozilla.org, a k a AMO


Your add-ons are listed here: addons.mozilla.org/en-US/developers/addons
Add-on URL: addons.mozilla.org/en-US/firefox/addon/your-configurable-addon-slug
Public data: current version, last update time, compatible browser versions, website and, optionally: all add-on detail metrics, if the developer wants to share them (excellent!)
Public metrics: total download count, average rating, number of ratings
Detail metrics: TONS: mainly installation rate and active installed user base over time, broken down by all sorts of interesting properties or in aggregate, graphed and downloadable in csv format. Notable omission: add-on page traffic stats. Public example: Greasemonkey stats
Developer page linked from the public add-on page when you're logged in: NO
Release process: Manual review process that can take a really long time, as AMO often is under-staffed, and hasn't successfully incentivized developer participation in the process to an extent as to make it not so.

Summary: great stats and an ambition to make information public and transparent.




Chrome add-ons: chrome.google.com/webstore, or the Chrome Web Store
Previously lived at chrome.google.com/extensions, the Chrome extensions gallery


Your add-ons are listed here: chrome.google.com/webstore/developer/dashboard
Add-on URL: chrome.google.com/webstore/detail/your-addon-signature[/optional-add-on-slug]
Public data: current version, last update time, if installed: a checkmark and the sign "Installed", instead of the "Install" button (excellent!)
Public metrics: total download count, average rating, number of ratings
Detail metrics: If you jump through the relatively tiny hoop of creating and tying a new Google Analytics account to your add-on, you get detailed add-on page traffic stats, over in Google Analytics. Notabe omission: all metrics about your installed user base :-/
Developer page linked from the public add-on page when you're logged in: NO
Release process: Automated review process, making yourself the only release blocker, in practice. This is bloody awesome!

In summary: A really delightful release process that doesn't waste your time. The metrics part is really disappointingly missing the most interesting data; I hope that will improve with time. There are other essential missing docs too: to find out that you can self host your add-on AND publish it in the chrome web store, with the same add-on id, you need excellent Google fu, or this secret knowledge:

  • first (before your initial web store submission) build your add-on locally
  • store the .pem file in some good location
  • rename it key.pem
  • copy that .pem file into the add-on directory
  • zip up that directory (so the top level of the zip file only has one directory)
  • NOW (and for all later versions, IIRC) upload this zip file to the Chrome Web Store
  • …and it will use your add-on signature, instead of that of Google's secret .pem



Opera add-on page

(slightly de-horizontalized screenshot taken here)

Opera add-ons: addons.opera.com/addons/extensions


Your add-ons are listed here: addons.opera.com/developer (this page is near impossible to find by navigation, and was the reason I created this blog post :-)
Add-on public URL: addons.opera.com/addons/extensions/details/addon-slug[/version (redirects visitors here)]
Add-on developer URL: addons.opera.com/developer/extensions/details/addon-slug/version (no redirect help, but links to all other versions)]
Public data: current version, last update time, add-on size (excellent!)
Public metrics: total download count, average rating, number of ratings
Detail metrics: NONE. Notabe omission: all data about your installed user base, AND add-on page traffic :-(
Developer page linked from the public add-on page when you're logged in: NO
Release process: Manual review process, rewarding the behaviour of publishing as little data about your add-on as possible, since each bit of data is a plausible blocker. (Example: it is a bad thing to link to your development site on github, unless it is a repository that only has Opera-addon-centric stuff in it, and not, say, covers the source code used to build add-ons all browsers it caters.)

Summary: young; still a far cry from easy to find your way around. I accidentally managed to log in via my email address (after having reset the password), which had gotten the same password as the account nickname I had published from before, but was otherwise treated as another account, with its own (empty) list of add-ons. So I first found no way to upgrade my existing add-on and just uploaded a new one. When I found the mistake, there was no way to abort the review process I had started (but I could edit it to add some reviewer notes for the probably equally confused reviewer). What probably looks like a really well integrated set of connected Opera sites to an Opera employee is a huge maze of web pages, none related to publishing your add-on, to an add-on developer.

All of these hosting sites have developer log-in of some sort, yet fail to link the developer's admin view from the public add-on page. For Opera, this hurts really badly, as there is so much Opera noise around, which does not try to help you publish your add-on; for the others, it's a smaller nuisance (it's also entirely possible that I learned where to find the "Developer Hub" and "Developer Dashboard" links long ago enough to now find them near intuitive).

Update: I just found Opera's dashboard link! Your logged-in name is the link that takes you to your dashboard of add-ons. And it only took knowing the wanted url, opening a web console and typing [].slice.call(document.links).filter(function(a){ return a.href == "https://addons.opera.com/developer/"; }) in it. What do you know? :-)