On Github yoavweiss / respimg-blinkon-presentation
BlinkOn - Zurich, May 2014
Working on responsive images in my spare time for the last 2 years
A member of the RICG
A Blink & WebKit committer
Prototyped picture in WebKit. Implemented srcset in Blink. Now implementing (the new) picture.
I also been working on front end optimization server side solutions for the last 15 years, and am on a personal vendetta on image bloat on the Web
Efficiently load properly dimensioned images that fit the page's design
(fragments)Who knows what the responsive images problem is?
It started out (or at least got people's attention) as a quality issue.
The solution to that was simple - just send users the big images
Mobile experience became better, but slower
"a responsive site" became a synonym of "a slow site"
Serving the same resources to mobile and desktop hurts performance
On mobile the images are much smaller and some of them are not even displayed
Images - over 61%
Up to™ 72% image data savings
tkadlec.com A small utility I cooked up and Tim Kadlec wrote about showed 72% data savingsdata plan abuse
This has turned out to be an abuse of our users data plans, which may be limited.Large images?
And abuse of our users' time. RWD sites got a reputation of being slow Web sites, mainly because of images.Turned into picture *with* srcset
The CG came up with the picture proposal, Hixie added srcset to the HTML spec.
A lot of mailing list flame wars. Things got tense.
Over time, the srcset syntax was adopted into the picture syntax, since they covered different use cases
Then after a long while of little progress
SrcN was proposed by TabAtkins and John Mellor, after a couple of meetups we had with John.
(John Mellor & Tab Atkins hashed it out over a bottle of wine, the legend says)It resolved all the use case, in a single element, but got resistence from some browser people.
The following an IRC chat I had with Simon Pieters, we figured out a way to gather up all the good pieces
from Src-N and wrap it inside something that looks really like the original picture syntax,
only significantly easier to spec, implement and maintain.
TabAtkins then revived the picture spec (basically rewrote most of it), and we've been working on it with Tab and
Simon ever since.
The RICG & whatwg/blink folks are working together on the spec, to make it as awesome as possible. Mozilla is also heavily involved
The implementation in Blink is moving along nicely, and Gecko are happily implementing as well.
If all goes well, we may have the feature sihpping in a few months.
Let's take a closer look at each one of the parts combining the latest spec.
The oldest part of the spec, goes back to the WHAWG 2012 days
<picture> <source media="(min-width: 45em)" srcset="large.jpg 1x, large-2x.jpg 2x"> <source media="(min-width: 18em)" srcset="medium.jpg 1x, medium-2x.jpg 2x"> <img src="small.jpg" srcset="small-2x.jpg 2x" alt="The president."> </picture>You can mix srcset's x descriptor with the overall picture syntax
<img src="small-1x.jpg" srcset="small-2x.jpg 2x" alt="The president.">
Today's Web have become fragmented when it comes to image formats.
We may not like it, but that's the truth :(
Picture will enable us to have client-side mime type fallback if we're using browser specific image formats, just like all other resources which they're type may or may not be supported (e.g. video, fonts).
Note that it doesn't mean that you can't do server-side content negotiation using the accept header, if that's your thing
But client-side may be more accessible to Web developers that can't mess around with their backend, and it has caching advantages.
<picture> <source media="(min-width: 45em)" srcset="large.jpg"> <source media="(min-width: 18em)" srcset="medium.jpg"> <img src="small.jpg" alt="The president."> </picture>
Here you can see the syntax parts that make up the "picture" part of the spec, namely the picture element and its source children.
Each one of the source children, as well as the img child define an image that fits into a certain responsive breakpoint.
<picture> <source media="(min-width: 45em)" srcset="large.jpg"> <source media="(min-width: 18em)" srcset="medium.jpg"> <img src="small.jpg" alt="The president."> </picture>
What's important to understand, and the big difference between this spec and the previous picture version, is that the img element is not optional
It must be there in order for an image to be downloaded and displayed on screen.
picture itself, is very much like a div, with the only difference is that img will look up the resource that it'd pick to download when picture is its parent.
http://ericportis.com/posts/2014/srcset-sizes/
The third part is IMO, the most exciting part.
This is the major innovation that the original src-N proposal brought
It's the most exciting since it applies almost everywhere, once you look at it.
It can be used to save bandwidth in both responsive and adaptive designs and even if hi res displays are not involved.
<picture> <source media="(max-width: 80em)" sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)" srcset="pic100.jpg 100w, pic200.jpg 200w, pic400.jpg 400w, pic800.jpg 800w, pic1600.jpg 1600w, pic3200.jpg 3200w"> <img src="otherpic.jpg" alt="The president giving an award."> </picture>
<img src="otherpic.jpg" alt="The president giving an award." sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)" srcset="pic100.jpg 100w, pic200.jpg 200w, pic400.jpg 400w, pic800.jpg 800w, pic1600.jpg 1600w, pic3200.jpg 3200w">
I started out by implementing srcset's x descriptor. It shipped in Chrome/Opera stable a few weeks back.
sizes and the 'w' descriptor in srcset are done. I'll probably aim to ship it in M37
picture work has started and is moving along nicely - Christian is helping with stable state
xxxx Indiegogo campaignThey're showing up on IRC and mailing lists, asking good questions.
Implemented srcset's 'x' descriptor
Willing to accept patches behind a compile flag
(fragments)They're not very enthusiastic about that.
PreloadScanner requires off-main-thread MQ eval
Getting picture and sizes to wrok requires MQ eval in the preloadScanner
Since the Bison parser and related classes are not thread safe, I had to create an alternative mechanism
Based on eseidel's CSS syntax tokenizer
Implemented the parts needed for MQs and sizes
http://en.numista.com/catalogue/pieces23200.html
I started by taking Eric's tokenizer and adapting it to my needs.
I've deleted the parts that I didn't need and implemented the missing parts that I did
Currently turned on only off-main-thread
Then I've build a parser for MediaQuery syntax that is based on the tokenizer's output
It's currently turned on only off-main-thread (so in the preloader, for 'media' attributes as well as the sizes stuff)
I plan to turn it on for all MQ evaluation soon, since it has better spec compliance, and it'd be easier to add stuff to it (e.g. calc support for MQs, MQ L4).
Used by MediaQueryEvaluator
Cached variant - contains static values
Dynamic variants - refs a LocalFrame
MQ eval no longer depends on RenderStyle
Implements thread safe CSS length computation
Uses MediaQueryParser as a component
Since 'sizes' syntax is based on CSS, I've used the Tokenizer also for the sizes attribute parser.
Calc syntax => tokens => reverse polish notation => length
Here again, I've used the Tokenizer to get the calc tokens.
Then I got rid of the parens by turning them into reverse Polish notation (Dijkstra's shunting yard algo)
And finally, calculate the output length
Parses the srcset attribute
'w' descriptors converted to DPR (using 'sizes')
Picks the best candidate to load
A stand alone parser for the srcset syntax. Used from both HTMLImageElement and HTMLPreloadScanner
Both the 'x' descriptor and the 'w' have an impact on the image's intrinsic size.
That means that when the image dimensions are not otherwise defined, the browser will use these values and the image dimensions from the image data itself to determine the display size of the image.
So, if you set these values incrrectly, they may imapct the way your image is displayed.Required to avoid double download
Also required for img attribute setting
Worked on by Christian Biesinger (Thanks, Christian! :))
In the HTML spec it is stated that images should start their download only after reaching stable state.
That means that HTMLImageElement is able to know who its parent node is (when set by parser) and avoid a double download
When set by JS, it means that JS running was terminated so that the order in which attributes are set on img doesn't matter
That wasn't how things worked in Blink though
I poked around a little bit with it (added tests and such), and then Christian Biesinger took it upon himself to make sure the spec makes it easier to be compliant and then align Blink's behaviour to the spec.
http://earnthis.net/brian-terrills-100-film-favorites-22-back-to-the-future-part-ii/
It's a complementary solution that allows for server side image adaptation, on top or instead of client side one
Future doesn't look bright, since Mozilla are opposed to it
336x635
106x200
211x400
336x635
770x512
200x200
400x288
770x512
No markup
single file
can download diff
complicated
decoding perf?
Fetching mechanism
@yoavweiss on Twitter & GitHub