Nice and easy lazy loading with lazysizes.js

Images play a large part in the reason why websites continue to grow in page size. While they don’t affect performance as much as JavaScript, they remain a burden on data and loading times. In this post I want to show you how to add lazy loading images as part of your workflow.

What makes a good lazy loaded image?

Before I get into the how, I want to quickly list some things I believe makes good lazy loading.

  • Has a fallback when JavaScript is disabled
  • Will work with srcset, retina, etc.
  • Doesn’t make the page ‘jump’ about as the images load
  • Doesn’t force you to change your markup structure
  • You can customise the loading
  • Doesn’t depend on the likes of jQuery

The fact they don’t affect performance like JavaScript, and aren’t always needed in the page, this means you can lazy load all the things
and reduce page size and requests significantly.

Example

Each of those things can be compared here, albeit you may need to view the Codepen on a slow connection!

See the Pen lazy loading images
by Steve ( @stevemckinney
) on CodePen
.

Lazy loading with lazysizes.js

Now to get into how to achieve lazy loading, using lazysizes.js. You have a fair amount of libraries to choose from, but I chose lazysizes.js for it’s vanilla JavaScript, simplicity, and plugins for extra functionality—like lazy loaded background images. It also has a bunch of events which you will utilise.

Setup

To begin using lazysizes, download and include lazysizes.min.js
or a method that suits your project best
.

...everything else



Basic markup required for lazyloading images

At it’s most basic there is no additional JavaScript setup required. It’s mostly done through HTML and CSS.

The main differences here are relatively small, the src
and srcset
attributes become data-src
and data-srcset
. The class
is a requirement too.

That’s all you need to make your images lazy load
. However, left like this there will be no indication the image is loading and page load itself will feel janky.

Making the load smoother

To take away the page jank as images load, you need to use the intrinsic ratio technique
for sizing the images.

As they don’t exist on page load, so there is no way for the browser to know the dimensions. The browser can’t predict the space required. The way this is solved is by creating a ‘placeholder’ and positioning the image over that.

Adjust the markup

The first step to do this, is to adjust our current markup. The only change is to add a div
round the image. This is so the image inside has a reference, to be placed and sized correctly.

The image
class name will be used to apply the image sizing and placement with an intrinsic ratio. This div
can also be used to indicate something is happening. So additionally a loading
class name has been added.

The fallback

You’ll notice the
tag in there too. This is treated as a regular image, no data attributes. As when JavaScript is disabled this will show instead.

The placeholder padding calculation

Just before getting into the CSS, you need to understand how to calculate sizing the images. The size is applied with a percentage padding.

( height / width ) * 100

This calculation is based upon the aspect ratio of the image. To calculate this you divide the height by the width and multiply by 100.

CSS for image sizing

This is called the intrinsic ratio method
, with a few additional lines of CSS, this sizes your image appropriately. A background gradient has been added to show something will be there.

.image {
  position: relative;
  padding-bottom: 66.5492958%;

  // Tweak as needed
  background: linear-gradient(rgb(242, 242, 242) 66%, rgba(242, 242, 242, 0)); }

.image img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 2; }

Another benefit of lazy loading images is if the visitor doesn’t reach that image within the page it’s not something they have to download. For those with smaller data plans, it’s a good thing.

CSS for loading indicator

The loading
class will apply the loading indicator and also be used in JavaScript later.

@keyframes scaleout {
  0% {
    transform: scale(0); }

  100% {
    transform: scale(1);
    opacity: 0; } }

.loading:before {
  content: "";
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 50%;
  margin-top: -16px;
  margin-left: -16px;
  width: 32px;
  height: 32px;
  border-radius: 32px;
  animation: scaleout 1.2s infinite ease-in-out;

  // Tweak as needed
  mix-blend-mode: soft-light;
  background-color: rgba(0, 0, 0, .9); }

Essentially this is a kind of pulsing indicator using a pseudo element.

You’ll also notice mix-blend-mode
, this will mean that the loading indicator looks ideal over any background. There are other ways to indicate loading, a more skeleton style
or using other indicators
.

CSS to fade the image in

The final step to make it all seamless is to utilise the lazyload
class. This was added to the img
tag earlier and gets transformed into lazyloaded
. You can use this to transition the opacity, or whatever you see fit.

.lazyload,
.lazyloading {
  opacity: 0; }

.loading,
.lazyload,
.lazyloaded,
.image {
  opacity: 1;
  transition: 2s cubic-bezier(0.215, 0.61, 0.355, 1); }

This bit of code appears a little messy, but each class is used at a different stage. So you need to ensure each of them has the appropriate transition and opacity.

Using events in JavaScript to clean up loading

lazysizes.js has a few events you can utilise to make changes. One of the things you can do is listen for the lazyloaded
event and remove the loading
class.

This can be used to stop the loading indicator running in the background. Which I can’t say for certain, but I’m sure it’ll help page performance slightly.

var lazy = function lazy() {
  document.addEventListener('lazyloaded', (e) => {
    e.target.parentNode.classList.add('image-loaded');
    e.target.parentNode.classList.remove('loading');
  });
}

lazy();

The code is using an event listener to listen for the lazyloaded
event. With the way the script works, to remove the loading
class you need to look at the current element e.target
and find its parent parentNode
.

Then you can remove the loading
class name.

What to do when JavaScript is disabled

As mentioned earlier the need for the image to show when JavaScript is disabled. When JavaScript is disabled you will still have the leftovers from the image which will be lazy loaded.

In your
you can add some CSS to hide this. It’s the most reliable way to do so.

  
    .image.loading { display: none; }
  

With the code in place your design shouldn’t look out of place, for the times when JavaScript can fail and when it’s disabled.

Flicker of a border around the image

Occasionally you may see a default browser border, this is because there is no src
defined in our example.

However, as recommended as part of the lazysizes.js documentation you can add a transparent pixel as the src
. This overcomes that problem. In general use I rarely see it, so I haven’t included it as part of the examples. It can make your HTML look pretty messy too!

Other effects

Here are some other ways of transitioning in the image. Have a look at the code, the CSS used is towards the top.

See the Pen lazy loading images-02
by Steve ( @stevemckinney
) on CodePen
.

You may also want to apply the whole effect to the container, so the text transitions in too. The JavaScript would need some slight modifications, but it can somewhat double up as a scroll effects library.

Summary

When I first set out with lazy loading images, I thought it would be a real pain. It isn’t without extra work, but it isn’t a huge hassle unless it’s with background images.

With most use cases you will be using the
tag, with changes in the attribute names.

稿源:iamsteve (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 前端开发 » Nice and easy lazy loading with lazysizes.js

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录