Image defer with srcset

Hi, I was having some problems with images pixelating. The problem was I wasn’t accomodating for device pixel densities and I wasn’t loading images to size. Here was my original code that was causing problems.

<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" alt="Discovery" width="110" height="110" data-src="http://www.modovis.com/wp-content/uploads/2015/12/Process-DYIcon600-1.png" />


I was able to fix the pixelation problem with this code:

<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" alt="Discovery" width="110" height="110" srcset="http://www.modovis.com/wp-content/uploads/2016/12/Process-DYIcon110.png 1x, http://www.modovis.com/wp-content/uploads/2015/12/Process-DYIcon600-1.png 2x" />

Though the pixelation is fixed, two new issues were created.

  1. It works on browsers that support srcset. How can I create a fallback for browsers that don’t support srcset? I know I would use src, but I’m already using src with my data:image placeholder to defer loading of the image.

  2. The images are no longer are deferring load. I changed data-src to srcset in my JS, but it still didn’t defer. I also tried using data-srcset, but it didn’t work either.

Does only data-src work for deferring images?

Looks like this is a js question because I’m guessing that the data-src attribute is a hook for the js to change the src of the image to the real image once the dom has loaded. Probably something like this.

If you are just supplying a better quality image for the double density device you could try this method instead.

I can move this to the js forum if the above is no help?

I believe the reason is due to the problem in this topic, I’m not sure you were in on it, so maybe you know how to tackle the source of the problem (image-rendering).

I didn’t take part in that thread but I guess most of the issue is as suggested and that the 600x600 has to be scaled down too far to get to 110x110. I would have made the image 220x220 and then scaled it down which should suit both double density and normal displays. Some images though may still not be as good and it depends on the image.

Of course here is such a wide variation between browsers and monitors that people don’t often see the differences that others see. I would have done those circles in css only and used a double size higher quality image for all the white images in the centre.

Of course as they are just black and white icons they would be better in svg and avoid the scalability issue altogether.

3 Likes

I did mention there using x2 size images and SVG.
But the big issue was the theme containing the image-rendering property and the OP had a hard time overriding it in a child theme for all browsers as they do/don’t support it in seemingly different ways.

Edit I don’t want to send this topic off topic, I just think it’s best to deal with a problem at its root if you can, before resorting to hacks and workarounds. So maybe continue this approach the first original topic, if there is any mileage in it that is.

The original problem cannot be solved for IE edge because it does not support the image-rendering properties and has discontinued -ms-interpolation-mode: which previously sorted out the problems in old IE browsers right back to IE7 as they always had problems with resizing images.

Therefore the only solution for IE edge is to use images of the correct size where this may be critical (as in circles etc). Alternatively as I suggested earlier perhaps draw the circles in css and just place the middle icon into the css circle assuming that transparent images are not required.

Regarding the question in this post about srcset then my first answer holds true I believe and the OP is already using a script to swap the src from the data-src attribute and therefore the same approach could be done for srcset. Use place holders for all images and then when the dom has loaded restore the correct image paths to all the sources in that rule.

Have a data-src attribute for the fallback image and then perhaps a data-srcset attribute for the srcet urls. Note data-src and data-srcset are ‘made up names’ that are used as storage containers that can be accessed independently (usually by script). people used to make up their own attributes so it was standardised using the ‘data-*’ attribute. It would presumably be just require a small change to the existing script (although I haven’t looked for it yet) to accomplish this.:slight_smile:

3 Likes

Back to the original question of changing the src of the image then as I guessed there is a script in the page that is swapping the data image for a real image.

The code is found here:

function init() {
    var imgDefer = document.getElementsByTagName('img');
    for (var i = 0; i < imgDefer.length; i++) {
        if (imgDefer[i].getAttribute('data-src')) {
            imgDefer[i].setAttribute('src', imgDefer[i].getAttribute('data-src'));
        }
 
    }
}
window.onload = init;

If we add data-src and data-srcset attributes to the image with the correct filenames then the js can be updated to match.

e.g. Html:

<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" alt="Discovery" width="110" height="110" srcset="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs 1x, data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs 2x" data-srcset="http://www.modovis.com/wp-content/uploads/2016/12/Process-DYIcon110.png 1x, http://www.modovis.com/wp-content/uploads/2015/12/Process-DYIcon600-1.png 2x" data-src="http://www.modovis.com/wp-content/uploads/2016/12/Process-DYIcon110.png">

JS:

function init() {
    var imgDefer = document.getElementsByTagName('img');
    for (var i = 0; i < imgDefer.length; i++) {
        if (imgDefer[i].getAttribute('data-src')) {
            imgDefer[i].setAttribute('src', imgDefer[i].getAttribute('data-src'));
        }
        if (imgDefer[i].getAttribute('data-srcset')) {
            imgDefer[i].setAttribute('srcset', imgDefer[i].getAttribute('data-srcset'));
        }


    }
}
window.onload = init;

That should then render the image tag like this:

<img src="http://www.modovis.com/wp-content/uploads/2016/12/Process-DYIcon110.png" alt="Discovery" width="110" height="110" srcset="http://www.modovis.com/wp-content/uploads/2016/12/Process-DYIcon110.png 1x, http://www.modovis.com/wp-content/uploads/2015/12/Process-DYIcon600-1.png 2x" data-srcset="http://www.modovis.com/wp-content/uploads/2016/12/Process-DYIcon110.png 1x, http://www.modovis.com/wp-content/uploads/2015/12/Process-DYIcon600-1.png 2x" data-src="http://www.modovis.com/wp-content/uploads/2016/12/Process-DYIcon110.png">

Remember to test thoroughly as JS isn’t my strongpoint.

One last thing to note is that the original pixellated images in IE edge seem to be caused by this swapping out the image routine. If in your original page you did not supply a data image the image comes out perfect when resized down to 110 in IE edge. It’s only when the image is subsequently swapped that it gets pixellated.

Probably a related issue I also note that (in IE edge) if on the same page you render the image at its natural size and at a small size as well it will make the smaller version pixellated once again. Displaying an image at a smaller size does not on its own make it pixellated unless you are already (or subsequently) showing the image at its natural size. If you display the image with width and height attributes of the natural size but size it smaller with CSS then once again it does not get pixellated. It’s very weird!

To test this out in edge just display a natural image smaller.

e.g.

<img src="images/img600.png" width="110" height="110" alt="test">

The image above is fine and not pixellated at the small size.

However if you do this then the small image looks pixellated.

<img  src="images/img600.png" width="600" height="600" alt="test">
<img  src="images/img600.png" width="110" height="110" alt="test">

Very weird indeed.

2 Likes

Paul, I tried both your HTML and JS rewrites. They worked perfectly. Images are displaying correctly at both 1x and 2x and also deferring load as I had hoped. I am going to play around with creating SVG’s and also creating the circles with css as you suggested. Thanks so much for all of your efforts!

3 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.