I'm using a CSS grid system which is based upon percentages. I have a grid with 4 columns, each 25% of the page's total width. I output my image tags inside of each "25% cell" like this:
<img src="foo.jpg" style="max-width:100%" />
As the browser resizes, the images also resize to fill in 100% of each 25% cell. The browser picks a height, as if I had put "height:auto" (which is implicit when omitted).
Now I want to add lazy loading capability to this. The problem is that before the images are loaded, their height on the page is unknown. The browser has to download the image & observe its aspect ratio, and calculate a height for it. Prior to this, all the images have a height of 1px. Since every image has a height of 1px, they are all considered as "within the viewport" and are immediately loaded.
Currently I have a proof of concept where prior to outputting the img tag, I calculate the images aspect ratio on the server, and output in a data attribute:
<img src="foo.jpg" style="max-width:100%" data-aspect="1.7742" />
Then, upon the event "document ready", I loop through every image and set a fixed 'height' value in pixels prior to lazy loading:
$('img').each(function() {
var img = $(this);
var width = img.width();
var ratio = img.data('aspectratio');
var height = width / ratio;
$(this).css('height', height+'px');
});
This seems to be working, in the sense that it no longer loads all the images at the same time, but only loads images as I scroll.
However, it seems like it could cause new problems, like the images becoming stretched as the user resizes the browser. I would have to switch the 'height' back to 'auto' when a callback fires for lazy loading having completed. That would take care of images the user sees - but the images below the fold would still have an improper 'height' value upon the browser being resized. Every time the browser is resized, I would have to iterate all images that were previously below the fold, measure their updated width, read their aspect ratio, and update the new height, and then retrigger lazy loading to handle anything that is now above the fold. If I don't do this, loading could be triggered too early or too late due to those images having the wrong height value.
My question is, is there any other ways to lazy load images with unknown heights, other than the exact method I've described here, and what ramifications would this have? Is there any downside to my method, other than it being a pain to program?