14

Ive mobile optimised my site with media queries. Everything looks how I would like it to but unnecessary images (as they're hidden with css) are being downloaded, slowing page loading times.

The easiest solution to this seems to be to replace as many inline images as I can with divs with background images. Then I can hide the div's with media query css for the mobile version.

I know there are potential downsides to this, outlined well in this post: When to use IMG vs. CSS background-image?

So the company logo, pictures of staff, etc will stay as inline images.

Are there any issues to my approach I havn't considered? Ive read a lot about mobile optimisation, particularly with media queries, and I havn't heard of anyone doing this even though it seems quite an obvious solution where images could be inline or background.

Note, ive done some experiments with iPhones and Android (im waiting to get some Blackberrys) and I know to stop background images downloading I need to set display none to the div's parent, not the div with the background image itself.

Note2, in an ideal world sites would probably have been built as mobile first but in this situation (and often in others) there is a limit to how much the original site can be modified.

Thanks

Community
  • 1
  • 1
Evanss
  • 23,390
  • 94
  • 282
  • 505
  • Without divulging too much, could you give us some idea of the context of the site? What *type* of content does it serve to what audience? etc.? – Moin Zaman Oct 26 '11 at 13:27
  • Im more interested in any potential issues with my solution so I can apply it (or not) to sites in the future. Mobile web usage is increasing very fast and I can definably see myself using my solution on a variety of sites so long as there are no issues im unaware of. Ive updated my question so make this clearer. Thanks – Evanss Oct 26 '11 at 13:48

7 Answers7

5

Unfortunately, there are no great answers for the problems you’re trying to solve.

First, you have the option of moving everything from img tags to css background images. As you note, you have to be careful of losing semantic meaning by doing so.

But even if you can move to background images without losing semantic value, it is still not going to be 100% reliable. I wrote a series of tests last summer. I retested them last week in preparation for the chapter in our book on mobile first responsive web design. The tests are located at http://www.cloudfour.com/examples/mediaqueries/image-test/.

Unfortunately, Android fails every one of those techniques. You can see it downloading multiple copies of the image files via Blaze’s mobile test: www.blaze.io/mobile/result/?testid=111031_96_316

UPDATE 3 Nov 2011: I’m currently trying to reconcile inconsistent results between what I see on Blaze and what I see using the same device in person. On my local Nexus S, it passes the fifth css test which limits the imgs by putting them inside the media queries. I watched the apache logs and confirmed the device only downloads one image instead of two for test 5. Blaze is running 2.3.3. My phone is running 2.3.6.

This is true for Android 2.2, 2.3 and 3.0. Hopefully, 4.0 will incorporate the webkit fixes that prevent this behavior: bugs.webkit.org/show_bug.cgi?id=24223

BTW, this seems to conflict with your comment about testing setting the parent div to display:none on Android. If you’re getting different results, I’d love to hear about it.

If you keep them as img tags, what are your options? On this topic, I have written a multi-part series. The second part in the series provides an in-depth look at the different techniques: http://www.cloudfour.com/responsive-imgs-part-2/

Again, none of the solutions are great. If you want something that is simple and will work most of the time, I’d go for adaptive-images.com. Or route images through Sencha.io SRC until we have a better solution for this problem.

BTW, sorry for having so many links that aren’t actually links. This is my first response on stackoverflow and it will only allow me to include two links.

grigs
  • 426
  • 3
  • 3
  • The main problem of the cookie-based solution is that it does not work on the first visit, which is the most important, especially for small business websites without a lot of regular visitors. E.G an hotel... – mddw Oct 31 '11 at 09:48
  • @mdi I agree. Very few sites will have the same ratio of return visitors as the Boston Globe. – Evanss Oct 31 '11 at 10:44
  • Sadly, the Boston Globe’s responsive images javascript isn’t working so mobile devices are currently getting large images on every visit. – grigs Oct 31 '11 at 18:08
3

If I'm understanding your question correctly, this seems like a perfect use case for srcset and sizes. This MDN article is a great post for learning the concept in-depth, but I will also summarize here. Here is a full, kind of complicated example:

<img srcset="elva-fairy-320w.jpg 320w,
         elva-fairy-480w.jpg 480w,
         elva-fairy-800w.jpg 800w"
     sizes="(max-width: 320px) 280px,
        (max-width: 480px) 440px,
        800px"
     src="elva-fairy-800w.jpg" 
     alt="Elva dressed as a fairy">

This code says:

  • If my browser doesn't support srcset use what is in src by default. Don't leave this out.
  • Hey browser, in srcset, here are 3 files and their natural widths separated by commas.
  • Hey browser, in sizes here are the widths of the space I want my image to take up depending on the media query. Use the one that matches first.

Then the browser itself will calculate which is the best image to use based on size AND screen resolution of the user then ONLY downloads that one which is pretty awesome in my book.

Sia
  • 8,894
  • 5
  • 31
  • 50
3

Why not do a mobile first approach and then use media queries to enhance bigger screens.

Also you can use media queries to serve specific CSS files.

With the inline images I have tried a script block in the head and immediately after the opening body tag, which runs only for mobile devices (detect via classname added to body, or presence of a media query CSS file) that find all inline images with a certain class and empty the src attribute.

see here Prevent images from loading

<script type="text/javascript" charset="utf-8">
    $(document).ready( function() { $("img").removeAttr("src"); } );
</script>

another way is to use url re-writing with mod rewrite and .htaccess or url rewrite module for iis. redirect user agent strings for mobiles to a small blank image.

see: A way to prevent a mobile browser from downloading and displaying images

RewriteCond %{HTTP_USER_AGENT} (nokia¦symbian¦iphone¦blackberry) [NC] 
RewriteCond %{REQUEST_URI} !^/images/$
RewriteRule (.*) /blank.jpg [L]

you can improve the above by loading your inline images from a different sub-domain and rewriting only those for mobile, as you don't want to rewrite all images (logo etc.)

Community
  • 1
  • 1
Moin Zaman
  • 25,281
  • 6
  • 70
  • 74
  • Id love to do a mobile 1st approach but im modifying an already built site (that i didnt build). – Evanss Oct 25 '11 at 15:14
  • Im concerned about detecting user agent strings, partly from a maintenance point of view, but also because ive read its not completely reliable. – Evanss Oct 25 '11 at 15:15
  • You would most likely want to keep an eye on my other [related question](http://stackoverflow.com/questions/7890840/most-efficient-way-to-cater-for-different-web-devices) – Moin Zaman Oct 25 '11 at 15:21
  • If I understand the 'Prevent images from loading' method, as javascript is run after the html and content are downloaded, the method only works if the images arn't in the html and instead are loaded only through javascript. Surely not all desktop / laptop users will have javascript? – Evanss Oct 25 '11 at 15:21
  • I saw, try the user agent strings. A lot of companies make a living off that, think all analytics companies. – Moin Zaman Oct 26 '11 at 07:01
  • Im still nervous about using agent strings if my method would also work, as it uses a standard technology. It would also be much less work for me as its using a technology I already know. – Evanss Oct 26 '11 at 09:18
  • I have one more idea. How about loading the default site with all inline images as blank images. Then detect the device using media queries or JS, or via screen size and for thte bigger sizes only, replace the blank images with the actual images, from a JS array or via AJAX? – Moin Zaman Oct 26 '11 at 09:49
  • Wouldn't it be terrible accessibility to load inline images as blank images without js? – Evanss Oct 26 '11 at 11:04
  • It depends, if accessibility is for vision impaired people, you'd hope to make it up with content and image captions. Its ultimately a balance I think. Server the best experience to mobile devices and screen readers. Screen readers these days can run javascript btw. – Moin Zaman Oct 26 '11 at 12:34
  • But a certain amount of non-visually impaired users will still have js disabled. – Evanss Oct 26 '11 at 12:41
  • You could have a link to an accessible version of the page that does things normally.. or a link to an alternate page with just the images? – Moin Zaman Oct 26 '11 at 12:43
  • Well then i might just as well have a separate mobile version of the site. – Evanss Oct 26 '11 at 12:58
  • Maybe tell us more about the actual site. It really depends and will help to understand the context. It may actually be the case for your specific site that having a separate site is the solution? – Moin Zaman Oct 26 '11 at 13:03
  • Sorry, but I dont want to divulge my company site here. My solution that I proposed in my question is easy to implement and maintain, and seems perfectly effective. I was just wondering if there was an issue with it I hadn't considered as I havn't heard of others using the same idea. Thanks – Evanss Oct 26 '11 at 13:23
2

Ok, important thing to note is that mobile != low bandwidth != small screen and desktop != high bandwidth != large screen.

What you probably want is to make a decision based on client bandwidth and client screen size. Media queries only help with the latter.

David Calhoun has a great writeup on how to do this here: http://davidbcalhoun.com/2011/mobile-performance-manifesto

Highly recommended.

bluesmoon
  • 3,918
  • 3
  • 25
  • 30
1

I stumbled recently on a great blog article on the subject, adressing the problem of responsive images (ie serving smaller images on smaller devices). The comments of the article are the most interesting part, and I think the replacement technique coined by Weston Ruter is a promising one :

http://jsbin.com/ugodu3/13/edit#javascript,html,live (look at the other iterations in the comments).

It has lots of caveat (and is maybe difficult, but not impossible, to merge in an existing website, as the affect all your non absolute links, not only imgs), but I will try it (merged with a lazy loading) on my next project, which is a responsive website that my designer made quite heavy (and he does not want to make it lighter). Note that you could combine this to a php script resizing the images on demand if your server supports it.

The others common solutions for responsive imgs are cookie based (check Filament Group Responsive images plugin).

I prefer responsive images to css background because they're more correct semantically and parse-able SEO-wise. If I agree that we should not assume that bigger screen = more bandwidth, we lacks tools to address this (navigator.connection is Android only.) so assuming that most mobile users have a crappy 2G/3G connection is the safest way.

mddw
  • 5,570
  • 1
  • 30
  • 32
0

I'm not sure if you have thought about doing this but one of the things you can do is check for the width of the screen resolution with javascript and then if the resolution is less than some number (I use 480 because at that point that site looks bad) then switch the css templates from the default to the mobile themed template.

function alertSize() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  }
  if (myWidth < 48)
  {
   switch css template to mobile template
  }
}
CBRRacer
  • 4,649
  • 1
  • 23
  • 27
  • If I load normal css first and then load additional styles with js, the background images from the normal css will already have been downloaded. – Evanss Oct 26 '11 at 17:14
  • If I use js to determine which styles to load, then wont no styles be downloaded if a desktop user doesn't have js? – Evanss Oct 26 '11 at 17:15
  • @jdln if you load the script in the head that tests for screen resolution prior to loading your css file this shouldn't be a problem. here's a link that helped me understand this. http://uxmovement.com/content/why-you-should-place-style-sheets-before-scripts/ – CBRRacer Oct 26 '11 at 20:13
  • @jdln yes this could cause a problem if they disabled javascript. You can use the noscript in the head with HTML5 compliant browsers which would resolve this issue – CBRRacer Oct 26 '11 at 20:19
0

Adapting to an existing site sucks but we do what me must. Here is how I solved it when importing a blog's feed into a mobile site. It scales the existing image on the page to the page's width ONLY if it's larger than the screen.

var $images = $("img[width]");
    $images.each(function(){ 
      try{
          var $image = $(this);
          var currentWidth = Number($image.attr("width"));
          if(currentWidth > screen.width){
              $image.width("100%");
              $image.removeAttr("height");
           }
      }
      catch(e)
      {/*alert("image scale fail\n"+e)*/}
 });

By making the width 100% and removing any height attribute, the image will scale perfectly to take up the full width whether you're in landscape or portrait orientation.

Chances are, the images on your regular site are already web optimized. There's usually not that much performance boost to be gained by loading smaller images. Reducing HTTP requests will make much more of a performance boost than bringing over smaller images. It may not be the perfect solution but it is certainly going to be the least maintenance. If you can't reasonably control what images are going to be used on the site, this is a pretty reasonable solution. If nothing else, maybe this will spark another idea for you.

sgliser
  • 2,071
  • 12
  • 13