
The Clown Car Technique for Responsive Images - joshuacc
https://github.com/estelle/clowncar
======
estelleweyl
The clown car technique -- used for foreground images in your HTML documents,
works best when the SVG contains only background images . If you use <image>,
all the images in the SVG will be downloaded.

Yes, the SVG does "waste" a single HTTP request -- you get two http requests:
one for the SVG file and one for the image it downloads that matches the media
queries within the SVG. However, you can use a data URI within your HTML to
eliminiate the call to the SVG file. An example of this (in CSS) is here:
<http://jsfiddle.net/estelle/ZHrb2/>

The reason I called it Clown Car technique was because we're stuffing a whole
bunch of images into a tiny little file.

I am looking into this technique not just to solve the <picture> RWD image
issue, but also as a way to manage images. We currently separate content
(html) from presentation (css) from behaviour (js). I like the idea of
managing my assets separately as well. Thinking this helps along those lines.

~~~
sbouafif
I like the idea of separating the content from the presentation and the
behaviour. But I'd really like to automate this.

Is there a way in SVG to concatenate strings? (I never really used SVG and
can't find something on this in Google) .

Using JS I generally use the data attribute in html to set the image name and
add _small, _big, _huge depending on the window size. The JS script will
automatically set the right image. It's great but doen't work if there's no JS
support.

------
DigitalSea
I agree as a developer wholeheartedly we need a better way of adding in
multiple versions of an image for the plethora of resolutions and pixel
density's out there, but this technique feels a little hacky to me. I am a big
advocate of SVG (I use SVG extensively for icons and logos especially) but
cramming media queries and image tags within to save a few bytes at the added
cost of complexity and browser quirks to debug doesn't feel like it's worth
it.

The only solid fix for responsive imagery is a HTML5 tag that allows you to
set breakpoints for different sizes. The proposed "picture" tag which is
similar to that of the video tag does what we want, but we most likely won't
see any action on this tag until 2014, possibly 2015 if this W3 bug ticket is
any indication: <https://www.w3.org/Bugs/Public/show_bug.cgi?id=18384>

This jQuery script adds in the functionality for using the proposed tag now
though, I can't speak for how well it works, but it looks promising:
<http://jquerypicture.com/>

~~~
est
JPEG/GIF/PNG all have interlaces, why not download the first scan for smaller
image, and full scan for original images?

~~~
dclowd9901
Wow, this is a pretty novel approach; is this something that's been talked
about or are you just one of those really clever people I keep hearing about?

~~~
est
I just learned it from my other question on Stackoverflow not long ago

<http://stackoverflow.com/questions/15674880/>

It's a cool hack which you can serve low-res, monochrome jpeg in the first
scan, and gradually to full-res, full-color jpeg.

------
WiseWeasel
I love how this isolates the complexity of responsive image serving from the
CSS. I wonder if a good practice might be to have a single images.svg file
with all your site's responsive images included as ID'd groups, like:

    
    
      <g id="logo">
        <image id="1x" xlink:href="logo_low_rez.png" />
        <image id="2x" xlink:href="logo_high_rez.png" />
      </g>
      <g id="promo">
        <image id="1x" xlink:href="promo_low_rez.png" />
        <image id="2x" xlink:href="promo_high_rez.png" />
      </g>
    

Then, you could render the content as such:

    
    
      <img src="images.svg#logo" />
      <img src="images.svg#promo" />
    

I'll have to play with this, but it looks like a promising idea. Here's hoping
browser compatibility is decent. For some reason, the first 'foreground' svg
example doesn't seem to render an image for me in Chrome or Firefox, despite
supposed support for the latter:

<http://estelle.github.io/clowncar/>

This could be a problem; I'd like to see expanded browser support.

~~~
neilk
If you compiled data about every image on the site in one file, and then
loaded that file with every request, you could just use regular CSS and media
queries.

------
jeffehobbs
Oh Dear Lord Picture Element Needs To Be Baked Into Browsers Soon

~~~
dminor
Yes.

> We can work with the browser vendors to get this CSP lifted.

No, let's work with the browser vendors to implement something more sensible
than stuffing background image media queries into a god damn svg.

------
benjoffe
> In the second, the raster images are background image. Only the required
> image is downloaded.

The author neglects to point out that every image will waste a http request
downloading the svg file so this is going to give poorer performance than
having the logic in your css (perhaps he considered it too obvious).

~~~
duskwuff
Surely this can be solved by embedding the SVG in a data: URI?

~~~
michaelbuckbee
That would reduce the number of HTTP requests to one (but would also have the
side effect of pulling in ALL of the different sized files)

~~~
mistercow
Why? It's not including the images in the data URI, just the SVG. That should
act identically to downloading the SVG as a separate file (minus the extra
HTTP request), unless I'm unaware of some very dumb quirk.

~~~
estelleweyl
including the data uri for the svg only makes sense. to include the data uri
for all the images would be the same weight as downloading all the images plus
about 10%.

The method at this link: <http://estelle.github.io/clowncar/bgonly.html> only
does two http requests, the svg and the image used. We can bring that down to
1 by using data URI for the svg logic only.

------
lazyjones
This is too hacky and too complex. It creates another level of cruft where we
already have too many of those.

Serving images according to pixel densities should be handled completely on
the server side. This can be done based on HTTP headers and in border cases
with a cookie denoting increased pixel density (i.e. N phyiscal pixels are 1
"HTML" pixel in width/height attributes), which can be set using JS. Ideally,
we'd have a HTTP request header for this (Accept-*).

For now, you can still get good results with higher resolution images where
maximum detail is desired (browsers scale images down nicely nowdays and users
actually appreciate being able to save higher-resolution versions) and
lower/normal where loading times are important (i.e. everywhere else).

------
polemic
Nifty, although I personally think that you might as well just use CSS and
save the HTTP request.

Of course, if you are going to use SVG, by all means provide _V_ ector _G_
raphics where you can!

------
hallman76
This reminds me of Shadow DOM.

Seems like you could use this technique to implement rich widgets like video
players, social sharing buttons, or ad units.

------
mildweed
Better yet: Intention.js.

<https://news.ycombinator.com/item?id=5587504>

------
marshallford
I've read through the article and can't determine what the downsides of this
technique. Lack of browser support?

~~~
lbotos
As far as I can tell, yes exactly that. Needs testing and the CSP issue as
well.

------
rplnt
It really breaks user experience though. So probably not the best way.

~~~
estelleweyl
In which way does it break user experience. Would like to know so I can try to
address that and figure out a work around.

~~~
rplnt
Right click -> save image/send image/etc; For some reason I haven't had those
options (although they are present on normal svg) and I think it would only
download the svg anyways (with the actual content left online).

~~~
estelleweyl
Thanks. Will look into that next week

------
aceperry
I thought this article was going to be about how the republicans ran the 2012
presidential campaign.

------
ck2
I suspect javascript based lazy image loading is superior?

