Last active
February 3, 2016 03:24
-
-
Save davidpaulsson/10101172 to your computer and use it in GitHub Desktop.
Lazy loading with padding-bottom hack for responsive images
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Place this inline at the bottom of the html document, right before | |
* closing `</body>`. It's important to have this inline as we want to | |
* display images asap. | |
* | |
* Markup example for the actual images. It also calculates the image | |
* container using the [padding-top hack](https://gist.github.com/davidpaulsson/10101985), | |
* please do this calculation on the back end, before drawing the DOM. | |
* Current example can load three images sizes, customize to fit your needs. It | |
* also adds the calculated image URL as an data-original tag on the img element it creates, | |
* making it play well with [jQuery Lazy Load](http://www.appelsiini.net/projects/lazyload). | |
* | |
<div class="img-container" style="padding-top:((image.Height / image.Width) * 100))%"> | |
<noscript data-src-small="@image.GetUrl(ImageSize.Small)" | |
data-src-medium="@image.GetUrl(ImageSize.Medium)" | |
data-src-large="@image.GetUrl(ImageSize.Large)" | |
data-src-width="@image.Width" | |
data-src-height="@image.Height" | |
data-alt="@image.Text"> | |
<img src="@image.GetUrl(ImageSize.Small)" alt="@image.Text"> | |
</noscript> | |
</div> | |
* | |
* If you want the image to load directly, as a normal `<img>` tag, just | |
* add `data-src-fast="yes"` to the `noscript` tag and the calculated | |
* URL will be added as the src attribute on the img element it creates. | |
* | |
*/ | |
(function(win) { | |
'use strict'; | |
// Get screen pixel ratio | |
var screenPixelRatio = function() { | |
var retVal = 1; | |
if (win.devicePixelRatio) { | |
retVal = win.devicePixelRatio; | |
} else if ("matchMedia" in win && win.matchMedia) { | |
if (win.matchMedia("(min-resolution: 2dppx)").matches || win.matchMedia("(min-resolution: 192dpi)").matches) { | |
retVal = 2; | |
} else if (win.matchMedia("(min-resolution: 1.5dppx)").matches || win.matchMedia("(min-resolution: 144dpi)").matches) { | |
retVal = 1.5; | |
} | |
} | |
return retVal; | |
}, | |
// Get the most suitable image | |
getImageVersion = function() { | |
var pixelRatio = screenPixelRatio(); | |
var width = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) * pixelRatio; | |
if (width <= 640) { | |
return "small"; | |
} else if (width <= 1024) { | |
return "medium"; | |
} else { | |
return "large"; | |
} | |
}, | |
// Load images | |
lazyloadImage = function(imageContainer) { | |
var imageVersion = getImageVersion(); | |
if (!imageContainer || !imageContainer.children) { | |
return; | |
} | |
var img = imageContainer.children[0]; | |
if (img) { | |
var imgSRC = img.getAttribute("data-src-" + imageVersion); | |
var altTxt = img.getAttribute("data-alt"); | |
var imgHeight = img.getAttribute("data-src-height"); | |
var imgWidth = img.getAttribute("data-src-width"); | |
var fast = img.getAttribute("data-src-fast"); | |
if (fast) { | |
try { | |
var imageElement = new Image(); | |
imageElement.src = imgSRC; | |
imageElement.setAttribute("height", imgHeight); | |
imageElement.setAttribute("width", imgWidth); | |
imageElement.setAttribute("alt", altTxt ? altTxt : ""); | |
imageContainer.appendChild(imageElement); | |
} catch (e) { | |
console.log("img error" + e); | |
} | |
imageContainer.removeChild(imageContainer.children[0]); | |
} else if (imgSRC) { | |
try { | |
var imageElement = new Image(); | |
imageElement.setAttribute("class", "lazy"); | |
imageElement.setAttribute("data-original", imgSRC); | |
imageElement.setAttribute("height", imgHeight); | |
imageElement.setAttribute("width", imgWidth); | |
imageElement.setAttribute("alt", altTxt ? altTxt : ""); | |
imageContainer.appendChild(imageElement); | |
} catch (e) { | |
console.log("img error" + e); | |
} | |
imageContainer.removeChild(imageContainer.children[0]); | |
} | |
} | |
}, | |
lazyLoadedImages = document.getElementsByClassName ? document.getElementsByClassName("img-container") : document.querySelectorAll(".img-container"); | |
for (var i = 0, length = lazyLoadedImages.length; i < length; i++) { | |
lazyloadImage(lazyLoadedImages[i]); | |
} | |
})(window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://www.smashingmagazine.com/2013/09/16/responsive-images-performance-problem-case-study/