I was looking for a good way to lazy load image son my website and stumbled upon https://www.botreetechnologies.com/blog/page-load-optimization-by-progressive-image-loading-like-medium. This post describes how to do image lazy loading similar to what medium does
- Show a
divthe same size as the resulting image (so the content does not “jump” after the image is loaded) - Load a very small low quality placeholder and blur it in the
div - Load the final image
I made it into a reusable shortcode
{{ $image := (.Page.Resources.GetMatch (index .Params 0)) }}
{{ $placeholder := $image.Resize "48x q20" }}
<div class="image_placeholder" style="max-width: {{$image.Width}}px">
<div class="placeholder" data-large="{{ $image.Permalink }}">
<img src="{{ $placeholder.Permalink }}" class="img-small">
<div style="padding-bottom: {{ div (mul $image.Height 100.0) $image.Width }}%;"></div>
</div>
</div>
that can be called using
{{% post-image "image.png" %}}
but only works with page bundle images to be able to use the Hugo image resizing functionality.
The JavaScript and CSS stay the nearly same as in the post, I just adjusted them for my theme
.placeholder {
background-color: #f6f6f6;
background-size: cover;
background-repeat: no-repeat;
position: relative;
overflow: hidden;
}
.placeholder img {
position: absolute;
opacity: 0;
top: 0;
left: 0;
width: 100%;
transition: opacity 1s linear;
}
.img-small {
filter: blur(50px);
/* this is needed so Safari keeps sharp edges */
transform: scale(1);
}
.placeholder img.loaded {
opacity: 1;
}
.image_placeholder{
display: block;
}
<script type="text/javascript">
window.onload = function() {
var placeholder = $('.placeholder');
placeholder.each( function(index) {
// 1: load small image and show it
var smallImgElement = $(this).find('.img-small');
var img = new Image();
img.src = smallImgElement.attr('src');
img.onload = function () {
smallImgElement.addClass('loaded');
};
// 2: load large image
var imgLarge = new Image();
imgLarge.src = $(this).data('large');
imgLarge.onload = function () {
imgLarge.classList.add('loaded');
};
$(this).append(imgLarge);
})
}
</script>
You can see it in action at https://blog.kulman.sk/, especially in the Projects section.
