/ Loading

Lightweight transitionable image lazy loading for Vue.js 2

Lightweight transitionable image lazy loading for Vue.js 2

Vue Clazy Load

Component-based lazy (CLazy) load images in Vue.js 2.

This component approach swaps slots based on the image's loading state. Thus allowing you to use anything as a preloader, such as component frameworks' spinners and progress bars. Such method also enables transitioning between states, a designer's dream.


Select one:

  1. Install using npm
npm install vue-clazy-load --save

You can omit the --save option if using [email protected]^5.

You can also use Yarn (recommended) as:

yarn add vue-clazy-load

Then in your JavaScript file:

import VueClazyLoad from 'vue-clazy-load' // ES6 (Babel and others)

- or -

var VueClazyLoad = require('vue-clazy-load')
  1. Embed script tag

Locally installed via npm/yarn:

<script src="node_modules/vue-clazy-load/dist/vue-clazy-load.min.js"></script>

Or from CDN:

<script src="https://unpkg.com/vue-clazy-load/dist/vue-clazy-load.min.js"></script>

Lastly, register the component into Vue:



Using Clazy Load is easy. The HTML code you need is the following:

<clazy-load src="https://unsplash.it/500">
  <img src="https://unsplash.it/500">
  <div class="preloader" slot="placeholder">
    Loading message

And no JS code is needed whatsoever, Clazy Load works out of the box.


The component needs some configuration, though. There's only one required option, keeping it pretty simple.

Prop Description Type Default
src Image source that will be loaded. String required
tag What tag the component will render to, like vue-router router-link component. String div
element Selector for IntersectionObserver's root element. Leave blank to use viewport. See below for more details. String null
threshold Values for IntersectionObserver's threshold option. See below for more details. Array/Number [0, 0.5, 1]
ratio Element visibility percentage to compare and trigger loading. Must be between 0 and 1. Number 0.4
margin IntersectionObserver's margin option. See original documentation for more details. String '0px'


Custom classes on the Clazy Load component are passed to the rendered output.

Also, the component adds loading and loaded classes to the root element regarding the two possible states, enabling further customization with CSS.


There is currently one event available for you to listen to on the component.

Event Description
load Event emitted when image finishes loading
error Event emitted if the image fails to load for whatever reason

Sub-components and elements

The reason the component has a src prop while the <img> does as well is to unbind them and allow you to use whatever you want in the default slot. For instance, a simple case in which you would separate the image from the loader:

<clazy-load src="imgsrc">
  <figure class="image-wrapper">
    <img src="imgsrc">
  <div class="preloader-wrapper" slot="placeholder">

Scroll watching behavior

Clazy Load uses the new IntersectionObserver API to watch for element visibility on screen. This way it is not only optimized due to use native browser API, it has no proprietary code or gimmicks watching for scroll and making checks, so it will be easier to maintain.

The downside is that this API is quite recent, so there still is small browser compatibility. Gladly, Polyfill.io covers this use case, and if you need to support older browsers, such as IE, you can include the following tag in your page:

<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>

Or simply add IntersectionObserver to the ?features= query of the URL if already using Polyfill.

The two configurable props element and threshold are bound to IntersectionObserver. element is used in a document.querySelector to pass the element to the root option, and threshold is used as it is. More details on those two options are available on MDN.