Vue progressive image loading plugin

Overview

vue-progressive-image

Vue progressive image loading plugin

alt tag

Installation

$ npm install vue-progressive-image

Usage

import Vue from 'vue'
import VueProgressiveImage from 'vue-progressive-image'

Vue.use(VueProgressiveImage)

Progressive image

Instead of using the normal img tag to load images

<img src="https://unsplash.it/1920/1080?image=10" />

use the progressive-img component already globally available after the plugin installation

<progressive-img src="https://unsplash.it/1920/1080?image=10" />

Progressive background

It is also possible to apply progressive images as backgrounds and it will have the same props as the progressive-img component

<progressive-background src="https://unsplash.it/1920/1080?image=10" />

Placeholders

To be able to immediately show some feedback to the user, it is possible to pass a placeholder image, which could be also 1% the size of the main image: it will be blurred so you can go crazy with optimizations here.

in this example I actually use the same image, but you have the idea here

<progressive-img
  src="https://unsplash.it/1920/1080?image=10"
  placeholder="https://unsplash.it/1920/1080?image=10"
/>

The slot (progressive-background only)

The progressive-background has a "content" slot, which can hold content that needs to be rendered over the background image and also can hold a preloader. This slot has one property called "visible" that tells you when, for example, a preloader needs to be visible or not.

<progressive-background src="https://unsplash.it/1920/1080?image=10">
  <div slot="content" slot-scope="{ visible }">
    <p>I am some content to display over the image</p>
    <div v-show="visible">I am the preloader</div>
  </div>
</progressive-background>

Blur

It is possible to adjust the level of blur applied to the placeholder image

<progressive-img
  src="https://unsplash.it/1920/1080?image=10"
  placeholder="https://unsplash.it/1920/1080?image=10"
  :blur="30"
/>

Ratio

It is possible to remove the padding that adds the aspect ratio to the container.

<progressive-img
  src="https://unsplash.it/1920/1080?image=10"
  no-ratio
/>

It is also possible to manually specify the image aspact ratio when you know it. It allows the placeholder to be displayed in the correct aspect ratio. The ratio is calculated as height / width.

<progressive-img
  src="https://unsplash.it/1920/1080?image=10"
  aspect-ratio="1.5"
/>

Image fallback

In case of a loading error of the main image, it is possible to add a fallback image which can display an error image or just another image.

<progressive-img
  src="https://this_url_should_cause_an_error"
  fallback="https://unsplash.it/1920/1080?image=10"
/>

Events

Each component emits an event whenever an image is loaded.

Because we usually load two images, a main image and a placeholder, two events are dispatched onLoad and onLoadPlaceholder

in your js file

export default {
  methods: {
    onLoad () {
      // main image is loaded
    },
    onLoadPlaceholder () {
      // placeholder image is loaded
    },
    onError (error) {
      // main image error
    },
    onErrorPlaceholder (error) {
      // placeholder image error
    }
  }
}

in the html just add the events you need to listen to

<progressive-img
  @onLoad="onLoad"
  @onLoadPlaceholder="onLoadPlaceholder"
  @onError="onError"
  @onErrorPlaceholder="onErrorPlaceholder"
  src="https://unsplash.it/1920/1080?image=10"
  placeholder="https://unsplash.it/1920/1080?image=10"
/>

Options

During the installation process it is possible to pass some default global options

Cached images

  • type: Boolean
  • default: true

Cached images are checked by default. This check kills the animation if the image was already loaded once. If you would like to show the animation every time, even when is not needed, you can simply use the plugin options like so:

Vue.use(VueProgressiveImage, {
  cache: false
})

placeholder

  • type: String
  • required: false
Vue.use(VueProgressiveImage, {
  placeholder: 'https://unsplash.it/1920/1080?image=20'
})

blur

  • type: Number
  • required: false
  • default: 5
Vue.use(VueProgressiveImage, {
  blur: 30
})

delay

  • type: Number
  • default: 0

This options is for debug only. It lets you have an easy look at the placeholder before the main image is fully loaded.

Vue.use(VueProgressiveImage, {
  delay: 2000 // 2 seconds before the image is displayed
})

Global options like placeholder and blur will be applied only to components that don't specify their own options

Examples

Check out the example folder in the root of the repository for a small vue page with some examples on how to use the plugin. If you want to add some new example, just make a PR and I will add them :)

Issues and features requests

Please drop an issue, if you find something that doesn't work, or a feature request at https://github.com/MatteoGabriele/vue-progressive-image/issues

Follow me on twitter @matteo_gabriele

Comments
  • Dynamic URL

    Dynamic URL

    Hi Gabriele, excellent work. It would be better if you add support for dynamical URL. For example i load my background image url from another server, and my default image url it's just empty string. When i received response from another server whit two urls (small and full image) and pass urls to my background component and then to progressive-background component, nothing happens. Maybe nothing happens because vue-progressive-image load image on mounted event of lifecycle hooks. Is it possible to add functional for loading dynamic images url. I think it would be very helpfull.

    bug 
    opened by distolma 15
  • Scroll stutter

    Scroll stutter

    Hi,

    I've noticed that when using this library with multiple images (not many, maybe 8), the scroll becomes jagged. And when replacing the progressive-background component with simple images the lag seems to be gone.

    Has anyone else experienced issues like this? Any idea on how to remedy this?

    note:

    In chrome dev tools rendering, when turning on "Paint Flashing" and "Scrolling Performance issues" nothing comes up. Also Chrome seems to be the most affected.

    reproduction needed 
    opened by maxim25 14
  • Not compatible with runtime-only build of vue

    Not compatible with runtime-only build of vue

    Hi,

    I'm trying to use your library in my project, however it fails for not being compatible with the runtime-only Vue:

    [Vue warn]: You are using the runtime-only build of Vue where the template option is not   available. Either pre-compile the templates into render functions, or use the compiler-included build. 
    (found in component <progressive-img>)
    

    As the runtime-only output a smaller size bundle, that would be great if you could provide a compiled version of vue-progressive-image.

    Also as a side note, are you considering an option to define srcset for multiple image resolutions?

    Thanks :)

    refactor 
    opened by Julien76 14
  • Allow aspect-ratio to be defined as prop

    Allow aspect-ratio to be defined as prop

    Currently the aspect ratio is auto detected for the (main) image. But the placeholder image will always be displayed with a default aspect ratio. I assume this is because the placeholder can be an image with different aspect ratio of the main image.

    This change will allow the aspect ratio to be explicitly defined with a prop. If its not defined, the behavior is as before.

    opened by merijnvdk 12
  • Don't know how to get this to work in a vue-pwa, or a .vue single-file component...

    Don't know how to get this to work in a vue-pwa, or a .vue single-file component...

    Having trouble making this work in .vue single file component inside a vue-pwa template app...

    first off... dunno where...

    Vue.use(VueProgressiveImage)
    

    ...is supposed to go or what it's purpose is. my 'main.js' file looks like this...

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    import VueProgressiveImage from 'vue-progressive-image'
    
    Vue.use(VueProgressiveImage)
    
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    
    new Vue({
      el: '#app',
      router,
      template: '<App/>',
      components: { App }
    })
    

    ...dunno if that is how it's supposed to be set up in the main.js file.

    So, the component .vue file I'm trying to add vue-progressive-images to looks like this inside the script tag:

    <script>
      import VueProgressiveImage from 'vue-progressive-image'
    
      export default {
        components: {
          'vue-progressive-image': VueProgressiveImage
        }
      }
    </script>
    

    ...then I'm creating a slot in the template of the .vue file to use for the placeholder image tag, like so...

    <slot name="background-image"></slot>
    

    ...then I'm trying to add this progressive-image html tag to a slot in an instance of the component, like so...

    <progressive-img
            slot="background-image"
            src="../../assets/images/featured/venice-scene-1920x1200.jpg"
            placeholder="../../assets/images/featured/venice-scene-512x320-placeholder.jpg"
            alt="A sample google virtual tour."
          />
    

    but I'm getting this error message for both the src and placeholder images:

    screen shot 2017-06-27 at 4 02 01 pm

    but that same file path worked just fine before I tried to add the progressive-img tag, so I'm confident that this is not the problem.

    Anyway, don't know how to make this work or fix it, so anything you can suggest would be awesome!

    Thank you :-)

    R

    needs more info 
    opened by rchrdnsh 11
  • Make fade-in duration a customisable parameter

    Make fade-in duration a customisable parameter

    Thanks for creating this great module. I have one request. Before the placeholder is loaded, the image is faded in from grey (as it seems), but this goes a little bit too slow for my taste. Would it be possible to make this fade-in speed customisable per parameter, as you currently also already allow for blur amount and delay?

    help wanted refactor feature 
    opened by dschreij 10
  • Duplicate elements showing when adding style to progressive-background

    Duplicate elements showing when adding style to progressive-background

    Description

    Duplicate elements showing when adding style to progressive-background

    Expected behavior

    Show the elements inside only once

    Actual behavior

    The elements get duplicated

    Environment

    npm ls vue-progressive-image: -- [email protected]

    1. Operating system: Windows 10 Pro
    2. Browser and version: Google Chrome - Version 66.0.3359.181 (Official Build) (64-bit)

    Reproducible Demo

    I created a new vue app and placed this in the generated Home.vue

    <progressive-background style="height: auto; overflow: hidden; padding: 15px" src="https://picsum.photos/200/300/?blur">
        <p style="margin: 15px 0 0 0; font-weight: bold;">JOHN DOE</p>
    </progressive-background>
    

    Result: screenshot_32

    If I remove style from progressive-background then the content will only show once

    needs more info 
    opened by leah-pgdn 8
  • Adding IMPORT causes blank page

    Adding IMPORT causes blank page

    If you are reporting a bug, please fill in below. Otherwise feel free to remove this template entirely.

    Description

    When I try adding, import VueProgressiveImage from 'vue-progressive-image' to my app.js file, in my Laravel project, the compiling the app returns a blank page. I remove the import, and my app loads as expected. Can figure out the issue!?

    Environment

    Run this command in the project folder and fill in the result:

    npm ls vue-progressive-image: [email protected]

    Then, specify:

    1. Operating system: Mac OSX
    2. Browser and version: Safari/Chrome (Latest)
    reproduction needed 
    opened by mbarwick83 8
  • Can this be used in server-side rendering?

    Can this be used in server-side rendering?

    The easiest example is how do I set up to use vue-progressive-image in nuxt.js?

    ssr: false, or if (process.BROWSER_BUILD) {} setting.

    -- The error message is as follows.

    [Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. HTML markup, for example nesting block-level elements inside

    , or missing . Billing hydration and performing full client-side render.

    enhancement help wanted refactor 
    opened by ghost 7
  • Cannot get this to work inside of my component...

    Cannot get this to work inside of my component...

    Soooo, I can get this to work with a basic image with basic CSS, like so:

    progressive-img {
      width: 100%;
      height: auto;
    }
    

    ...but I cannot seem to get it to work with more specific CSS inside of a custom vue component. the image simply does not show up at all.

    Can you see anything in this CSS that might be causing an issue with the plugin?

    This is the CSS of the parent component:

    .component {
      width: 100%;
      height: calc(100vh - 48px);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      position: relative;
      background: url(../../assets/images/logos/arrow-favicon-blue-10-percent.svg) no-repeat center 25vh, #091830;
    }
    

    and here is the CSS of the progressive-image, which is a child of the parent .component:

    progressive-img {
      width: 100vw;
      height: calc(100vh - 48px);
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      object-fit: cover;
      z-index: 1;
    }
    
    @media screen and (orientation: landscape) {
      progressive-img {
        width: 70vw;
        height: 100vh;
      }
    }
    

    Please let me know if you see anything, or if you need any more information to understand better. I looks like the image tries to load by flickering for a split second, but then it's gone, if that helps at all.

    ...I think it's almost there! XD

    R

    opened by rchrdnsh 6
  • Duplicate image after filtering tags/category/searchs

    Duplicate image after filtering tags/category/searchs

    Here's a preview of bugs: image

    That's preview after I filter tags/category/searches via ajax. I use Vue, and filter in same pages using ajax. The content (title & caption) displayed is correct (no duplicate), but only the real image is duplicate. Even when I check through inspectelement, the progressive img placeholder source is correct.

    Is it because of cache?

    And when I force to refresh with the same url, there is no problem. Here's the previews: image

    I'm really confused. I don't want to change the library,

    reproduction needed 
    opened by AnonimBella 5
  • chore(deps-dev): bump vite from 2.9.5 to 2.9.13

    chore(deps-dev): bump vite from 2.9.5 to 2.9.13

    Bumps vite from 2.9.5 to 2.9.13.

    Changelog

    Sourced from vite's changelog.

    2.9.13 (2022-06-27)

    2.9.12 (2022-06-10)

    • fix: outdated optimized dep removed from module graph (#8534) (c0d6c60), closes #8534

    2.9.11 (2022-06-10)

    2.9.10 (2022-06-06)

    2.9.9 (2022-05-11)

    2.9.8 (2022-05-04)

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Rendered image does not retain tailwind class

    Rendered image does not retain tailwind class

    Description

    Template without plugin:

    <img alt="gallery" class="block object-cover object-center w-full h-full" src="#">
    

    Template with plugin:

    <ProgressiveImage alt="gallery" custom-class="block object-cover object-center w-full h-full" :placeholder-src="#" :src="#" />
    

    HTML without plugin:

    <img class="block object-cover object-center w-full h-full" src="#" alt="gallery" style="">
    

    HTML with plugin:

    <div class="v-progressive-image block object-cover object-center w-full h-full" data-v-263c1f8c="" style="max-width: 4000px;">
    <div style="padding-bottom: 75%;">
    <img class="v-progressive-image-main" src="#" alt="gallery" style=""><!----><!----></div></div>
    

    Expected behavior

    Placeholder image and rendered image both retain the tailwind classes.

    Actual behavior

    Only placeholder image retains tailwind classes. Actual rendered image does not have the tailwind classes, which were incorrectly placed to the div.

    img class="block object-cover object-center w-full h-full" v.s. img class="v-progressive-image-main"

    Environment

    [email protected] MacOS Safari

    Thank you!

    opened by amecreate 0
Owner
Matteo Gabriele
Building things that might help other developers to build other things.
Matteo Gabriele
simplistic vue.js directive for image lazy loading

Vue Progressive Image Lazy load images while showing a preview. Super tiny, less than half a kilobyte minified and gzipped. usage v-lazy-img adds the

Norman 25 Aug 11, 2021
Vue 2 image and video loader supporting lazy loading, background videos, fixed aspect ratios, low rez poster images, transitions, loaders, slotted content and more.

Vue Visual Vue 2 image and video loader supporting lazy loading. Visual 2.x is a simplification of Version 1.x with a greater reliance on modern brows

Bukwild 56 Sep 9, 2022
Vue.js lazy load image directive with akamai image converter

vue-lazyload-akamai Vue.js lazy load image directive with akamai image converter ??

Blibli.com 2 Aug 13, 2018
🐌 A small size Vue.js directive for lazy loading images using IntersectionObserver API

?? vue-tiny-lazyload-img A small size Vue.js directive for lazy loading images using IntersectionObserver API Demo Page https://mazipan.github.io/vue-

Irfan Maulana 91 Nov 18, 2021
Flexible modal component for Vue with ability of asynchronous lazy loading

vue-async-modal Flexible modal component for Vue with ability of asynchronous lazy loading Usage Firstly, you should add Modal component in your templ

JounQin 37 Aug 30, 2022
A Vue lazy loading directive.

A Vue lazy loading directive.

Vue Interface 0 Feb 4, 2022
A vue component for sleek and optimal lazy loading

sloth-loader ?? Image Lazy loader Vue Component with intersection observer Example here Installation yarn add sloth-loader npm i sloth-loader import c

Kenny Krosky 0 Oct 21, 2021
A Vue.js plugin for lazyload your Image or Component in your application.

Vue-Lazyload Vue module for lazyloading images in your applications. Some of goals of this project worth noting include: Be lightweight, powerful and

Awe 7.7k Oct 3, 2022
A plugin of vue for image lazyload(vue图片懒加载插件)

中文文档看这里 Update v2.1.0 Add requestAnimationFrame polyfill. Now img lazyload detects horizontal direction automatically Imporve perfomence, since the sc

zhaoyenb 251 Aug 29, 2022
:camera: Mini Image Lazy Loader for P(R)eact and Vue

Pimg is a Progessive Image Component For React, Preact and Vue.js. It helps in lazy loading of images in a nice and cool way. It's 2KB (gzipped). It h

Ademola. 98 Apr 24, 2021
A small lazy image loader for Vue

lazy-vue lazy-vue is the easiest way to get a lazy image loader working within your vue projects. It is meant to be as simplest as possible, so you do

Gustavo Ocanto 63 Jul 19, 2022
Vue.js Image Kit Component with Lazy Load built in and Responsive Images

Vue Image Kit Vue.js Image Kit Component with Lazy Load built in and Responsive Images The inspiration comes from this and a talk from @derevandal in

Igor Guastalla 9 Mar 31, 2022
A super simple image lazy loader for Vue.

cube-vue-image-lazy A super simple image lazy loader for Vue. Install yarn add cube-vue-image-lazy Warning: You'll need to install the w3c Intersectio

Cube 4 Jun 19, 2020
Vue image lazyload directive

Vue image lazyload directive

alex koh 0 Nov 3, 2020
A Vue.js component to load an image automatically when it enters the viewport.

A Vue.js component to load an image automatically when it enters the viewport.

Ali Sarfaraz 0 Mar 29, 2020
Create lazy image, embed, video and element with animation just with attributes.

?? Lazy-attr v1.2.3 Create lazy loading request or element like image, iframe, video... Make custom animation on lazy and not lazy element on all brow

null 1 Jan 4, 2022
A lazyload plugin for Vue.js v2.x+.

vue-l-lazyload A lazyload and in-view detection plugin for Vue.js v2.x+. Demo Live demo or npm install vue-l-lazyload && npm run startDev to play it!

Light Leung 26 Mar 9, 2022
Vue Plugin for vanilla-lazyload

lazyload-vue Vue Plugin for vanilla-lazyload Build status: features Simple usage with v-lazy-src Accepts options Vue.use(LazyloadVue, options) Multipl

Kazap Tecnologia 29 Jul 14, 2022
A Lazy load plugin for Vue 3.x

vue3-lazy Status: Alpha. Lazy load plugin for Vue 3.x inspired by vue-lazyload. This plugin support very simple options, and easy to use. Install $ np

null 2 Feb 8, 2022