// Tutorial //

Lazy-Load Images In Vue.js with vue-clazy-load

Published on August 20, 2017
Default avatar

By Joshua Bemenderfer

Lazy-Load Images In Vue.js with vue-clazy-load

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Images are a fun part of web development. They look great, and are incredibly important in almost every app or site, but they’re huge and slow. A common technique of late is that of lazy-loading images when they enter the viewport. That saves a lot of time loading your app, and only loads the images you need to see. There are a number of lazy-loading solutions for Vue.js, but my personal favorite at the moment is vue-clazy-load.

It’s basically a dead-simple wrapper with slots that allows you do display a custom image and a custom placeholder. There’s not much else, but it’s incredibly flexible.


Install vue-clazy-load in your Vue.js project.

# Yarn
$ yarn add vue-clazy-load

$ npm install vue-clazy-load --save
main.js (Partial)
import Vue from 'vue';
import App from 'App.vue';
import VueClazyLoad from 'vue-clazy-load';




new Vue({
  el: '#app',
  render: h => h(App)

Since vue-clazy-load uses the brand-new IntersectionObserver API, you’ll probably want a polyfill to support it in most browsers. This one works well, but any polyfill that provides the IntersectionObserver API should work.

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


Now you can use the <clazy-load><clazy-load> component directly, as shown below.

  <div id="app">
    <!-- The src allows the clazy-load component to know when to display the image. -->
    <clazy-load src="https://baconmockup.com/400/400/">
      <!-- The image slot renders after the image loads. -->
      <img src="https://baconmockup.com/400/400/">
      <!-- The placeholder slot displays while the image is loading. -->
      <div slot="placeholder">
        <!-- You can put any component you want in here. -->

This will get you a basic div that starts loading once the element enters the viewport, displays Loading… until the image loads, then displays the image. Nice and simple!

There are, of course a few props you can pass:

  • src: String (required) - The src of the image to load.
  • tag: String - Which component / element clazy-load will render as. (The default is a boring 'ol div.)
  • element: String - Which element to consider as the viewport. Otherwise the browser viewport is used. (Useful if you have a custom scrolling area.)
  • threshold: Array<Number> || Number - How far into the viewing area the clazy-load component needs to be before the load is started. See MDN for more details.
  • margin: String - A value for the margin that gets applied to the intersection observer.
  • ratio: Number - A value between 0 and 1 that corresponds to the percentage of the element that should be in the viewport before loading happens.
  • crossorigin: “anonymous” or “use-credentials” - An option to help work with CORS for images hosted on a different domain.
  • loadedClass: String, loadingClass: String & errorClass: String - Class name to give to the root element for the different states.

There’s also a single event provided, the load event. Which is, as the name implies, emitted when the image finished loading.

Also of note, you can effectively use any components in the slots, including Vue transition components, as shown below:

  <div id="app">
    <!-- Boom: Free fade transitions. -->
    <clazy-load src="https://baconmockup.com/400/400/">
      <transition name="fade">
        <img src="https://baconmockup.com/400/400/">
      <transition name="fade" slot="placeholder">
        <div slot="placeholder">


.fade-enter, .fade-leave-to {
  opacity: 0;


I can’t think of a much easier way to handle image preloading. If you can, feel free to send us a message! For now though, I believe vue-clazy-load can handle pretty much any lazy-loading situation. Enjoy!

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up now
About the authors
Default avatar
Joshua Bemenderfer


Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
Leave a comment
Leave a comment...

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!