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
$ npm install vue-clazy-load --save
import Vue from 'vue';
import App from 'App.vue';
import VueClazyLoad from 'vue-clazy-load';
...
Vue.use(VueClazyLoad);
...
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.
<template>
<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. -->
Loading....
</div>
</clazy-load>
</div>
</template>
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:
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:
<template>
<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>
<transition name="fade" slot="placeholder">
<div slot="placeholder">
Loading....
</div>
</transition>
</clazy-load>
</div>
</template>
<style>
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
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.
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.
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!