A Vue.js component to lazy load an image automatically when it enters the viewport using the Intersection Observer API.
Check out the fundaments on how it's built in this Alligator.io article.
- Simple demo
- Responsive images, by @aarongarciah
- Progressive image loading with animations, by @aarongarciah
- Performant progressive blur using SVG
npm install v-lazy-image
Warning: You'll need to install the w3c Intersection Observer polyfill in case you're targeting a browser which doesn't support it.
You can register the component globally so it's available in all your apps:
import Vue from "vue";
import { VLazyImagePlugin } from "v-lazy-image";
Vue.use(VLazyImagePlugin);
Or use it locally in any of your components:
import VLazyImage from "v-lazy-image";
export default {
components: {
VLazyImage
}
};
You must pass an src
property with the link of the image:
<template>
<v-lazy-image src="http://lorempixel.com/400/200/" />
</template>
That image will be loaded as soon as the image enters the viewport.
You can use the src-placeholder
property to define an image that is shown until the src
image is loaded.
When the src
image is loaded, a v-lazy-image-loaded
class is added, so you can use it to perform animations. For example, a blur effect:
<template>
<v-lazy-image
src="https://cdn-images-1.medium.com/max/1600/1*xjGrvQSXvj72W4zD6IWzfg.jpeg"
src-placeholder="https://cdn-images-1.medium.com/max/80/1*xjGrvQSXvj72W4zD6IWzfg.jpeg"
/>
</template>
<style scoped>
.v-lazy-image {
filter: blur(10px);
transition: filter 0.7s;
}
.v-lazy-image-loaded {
filter: blur(0);
}
</style>
You could listen to the intersect
and load
events for more complex animations and state handling:
<template>
<v-lazy-image
src="https://cdn-images-1.medium.com/max/1600/1*xjGrvQSXvj72W4zD6IWzfg.jpeg"
src-placeholder="https://cdn-images-1.medium.com/max/80/1*xjGrvQSXvj72W4zD6IWzfg.jpeg"
@intersect="..."
@load="..."
/>
</template>
@jmperezperez has written about the progressive loading technique on his blog, in case you want a deeper explanation.
Using the srcset
property you can set images for different resolutions:
<template>
<v-lazy-image
srcset="image.jpg 1x, image_2x.jpg 2x"
/>
</template>
When using the srcset
attribute is recommended to use also src
as a fallback for browsers that doesn't support the srcset
and sizes
attributes:
<template>
<v-lazy-image
srcset="image-320w.jpg 320w, image-480w.jpg 480w"
sizes="(max-width: 320px) 280px, 440px"
src="image-480w.jpg"
/>
</template>
The srcset
prop is combinable with src-placeholder
in order to apply progressive loading.
Aside from the following API, you can pass any img attribute, such as alt
, and they'll be added to the rendered <img>
tag.
Fields marked as (*) are required.
Name | Type | Description |
---|---|---|
src |
String (*) | Image src to lazy load when it intersects with the viewport |
src-placeholder |
String | If defined, it will be shown until the src image is loaded. Useful for progressive image loading, see demo |
srcset |
String | Images to be used for different resolutions |
intersection-options |
Object | The Intersection Observer options object. |
Name | Description |
---|---|
intersect |
Triggered when the image intersects the viewport |
load |
Triggered when the lazy image defined in src is loaded |