
How to Use Responsive Images - yoav
https://blog.ycombinator.com/how-to-use-responsive-images/
======
Klathmon
If you are using Webpack to build your application, you can take advantage of
a fantastic loader called "responsive-loader" [0] which can automatically
build smaller and smaller versions of an image which can be dumped into a
srcSet automatically to give you a good amount of the benefits of responsive
images without a ton of work customizing each <img> tag in your application.

Combine that with my plugin "imagemin-webpack-plugin" [1] which will ensure
they are all compressed as well as you want, and you can get a fairly drop-in
solution to massively reduce the size of images downloaded while keeping
extremely high resolutions for user agents that want it, and without a ton of
manual work on your part!

I've always wanted to look into taking this a step further and somehow
determine the actual size of the image on the screen in various resolutions
and then generate more accurate image sizes and fill in the `sizes` attribute.
I've thought that you might be able to pull it off with some automated
headless browsing of the built app with some work, but I never got around to
trying it.

[0] [https://github.com/herrstucki/responsive-
loader](https://github.com/herrstucki/responsive-loader)

[1] [https://github.com/Klathmon/imagemin-webpack-
plugin](https://github.com/Klathmon/imagemin-webpack-plugin)

~~~
Rotareti
Fantastic! The webpack ecosystem maybe fiddly and overwhelming, but as soon as
you have a nice, solid selection of tools wired up and working it becomes very
powerful. I'm really excited about the two packages you mention. :D Thank you
for sharing this!

------
nightski
I get why this is done, and it is important. But look at the amount of effort
and time that goes into displaying a single image properly on the web
nowadays. It's just nuts.

It feels like we are slaves to the tech and not the other way around.

~~~
dbbk
You should read up on Client Hints. Allows the browser to automatically send
desired size and pixel density down the image request, where the CDN can then
serve up the appropriate file. Basically means for most cases you could go
back to using a single <img> tag.

It's Chrome only for now but it's a nice future.

------
tomcam
What is the compatibility with older browsers? Useful to know when designing
for countries with expensive bandwidth or outdated smart phones

~~~
mark242
[https://caniuse.com/#feat=srcset](https://caniuse.com/#feat=srcset)

------
yoav
Author here if anyone has follow up about the post, ama.

~~~
kellysutton
Nifty post. Always think the world could stand to learn more about
srcset/sizes.

About a year ago, I went all the way down the rabbit hole of programmatically
generating `srcset` attributes and wrote about it:

[http://kellysutton.com/2016/06/23/boiling-the-ocean-with-
mar...](http://kellysutton.com/2016/06/23/boiling-the-ocean-with-markup.html)

------
disconnected
Not a web expert here, but don't CSS media queries and "background-image:
url(blah/blah/blah.jpg)" already achieve pretty much all of this?

With the advantage that you have attributes (background-size, etc) to handle
image resizing and alignment without having to faff around with imgs, divs to
contain said imgs and a bunch of CSS rules for each for hours?

AND the advantage that you can have one single file for "media" definitions
that allows you to swap images around when needed (just change the url())
without having touch 347 HTML files just to set the image src?

Or maybe I am missing the point.

~~~
yoav
You could do that, but there's a performance benefit to doing it with
srcset/sizes in the html.

The cascading part of CSS means the a later rule could override an earlier
one, so to determine which image variant to download when looking at the css
the browser needs to parse the html, parse the css, link the two. A css rule
may end up not even applying to any elements on the page if a particular
selector has no matches. Only after all this can it begin downloading the
actual images.

Using srcset/sizes the browser parses the html and can begin downloading the
correct image variants immediately, before it parses css.

With prefetching enabled this means your browser could parse the html and
cache all the image variants on the page that you'll need when hovering over a
link to another page. So when you actually click on it everything is loaded
from cache and super fast.

It's up the browser to manage situations of lower network speed, pixel
density, etc. and to determine when and how much preloading to do. Using
srcset/sizes just gives the browser the option to optimize as much as needed.

~~~
disconnected
I think I understand what you are saying.

I did not consider the overhead of the browser parsing the CSS file and then
figuring out which rules are applied where and depending on what rules are
being applied, figuring out what else needs to be downloaded, etc.

But is that overhead really that significant? Or will the responsive images
approach merely shave off a few % off the page load time?

~~~
Klathmon
While I think that the overhead on it's own might not be that much, even
little gains of tens of MS can add up to improve the experience.

And something like srcSet will possibly allow the useragent to become
"smarter" in the future. Perhaps halving image size when low on battery, or
when on a limited mobile plan.

This isn't you choosing which image to serve who as a developer, it's serving
up a bunch of options and letting the useragent choose which it knows is best
for the user at that time.

------
vladdanilov
There's no accent in the article that images should be optimized for the
target screen dpi. It's wasteful to serve a 2x image for 1x screens and 1x
when 2x is already present on the page.

Almost all CDNs/services compress images lightly if at all, offline tools are
better at this, e.g. images from the reference page can be ~20% smaller.
Ideally, hidpi images should be compressed harder, e.g. lower JPEG quality.

~~~
yoav
Great points. The first article only lightly touches on those topics, in part
2 I'll talk more about the challenges and constraints that lead us to the
srcset widths we use at Webflow and our image processing / compression stack.

Hopefully talking about the 'why' will help others make the right choices for
their project.

The reference page will see improvements in the future as we enhance our
process, but certainly resizing and optimizing variants by hand can yield even
better results if you have the time.

What is worth noting from part 1 is that using pixel width variants in
`srcset` will let the browser factor in dpi of your monitor as part of the
calculation. So it wouldn't serve a 2x image where it only needed 1x.

It's not recommended to use high dpi images, 72dpi is the way to go for web
content, with a larger (dimensions) version serving as the 2x variant.

------
Scirra_Tom
Recently learnt in more depth around this, and did a really fun project to
automate this in an ASP.net control.

Input is:

    
    
        <Controls:ResponsiveImageFixedSize runat="server"
            Alt="Logo"
            ImagePath="/global/construct-3-logo.png"
            Width="43"
            DisableLazyLoading="True"
        />	
    

Renders as:

    
    
        <img width="43" height="44" srcset="https://s2.construct.net/images/v173/r/global/construct-3-logo_v43.png 1x, https://s2.construct.net/images/v173/r/global/construct-3-logo_v64.png 1.5x, https://s2.construct.net/images/v173/r/global/construct-3-logo_v90.png 2x, https://s3.construct.net/images/v173/r/global/construct-3-logo_v110.png 2.5x, https://s3.construct.net/images/v173/r/global/construct-3-logo_v130.png 3x" src="https://s2.construct.net/images/v173/r/global/construct-3-logo_v43.png" alt="Logo"/>
    

Works and looks great on high dpi displays. Lazy loading enabled renders
something like:

    
    
        <img class="jsEnabled" data-src="https://s1.construct.net/images/v173/r/home/monster_v350.png" width="350" height="367" data-srcset="https://s1.construct.net/images/v173/r/home/monster_v350.png 1x, https://s1.construct.net/images/v173/r/home/monster_v550.png 1.5x, https://s3.construct.net/images/v173/home/monster.png 2x" src="https://s1.construct.net/images/v173/1.gif" alt="Monster"/>
        <noscript>
            <img width="350" height="367" srcset="https://s1.construct.net/images/v173/r/home/monster_v350.png 1x, https://s1.construct.net/images/v173/r/home/monster_v550.png 1.5x, https://s3.construct.net/images/v173/home/monster.png 2x" src="https://s1.construct.net/images/v173/r/home/monster_v350.png" alt="Monster"/>
        </noscript>
    

At this point I was thinking that's actually a fair old chunk of text to
display an image, but still worth doing.

It can be quite fiddly doing this, but it's nice when it's done and works as
expected!

------
erickhill
If SVGs were embraced more broadly (and the standards team supported) many of
the raster images would fall to the wayside. These recommendations are still
totally valid for content-based images (photos, etc.).

Some sort of hybrid between the two, and the recs in the article, seem to be
the future of visual imagery online.

~~~
yoav
I'd love to also see something like FLIF get browser support.
[http://flif.info/](http://flif.info/) where the user agent could set a
preferred quality for images/variants based on network/device constraints. Or
download the first say 20% of images on a page, only downloading more after
staying on the page for a length of time.

------
jtbayly
Umm... How do I get to the post? It just takes me to the HN homepage.

~~~
jtbayly
Maybe it's my ad blocker on iOS.

