[Vuejs]-Lazy loading images in Vue/Laravel

0👍

Try moving the call to $("img.lazy").lazyload() into the mounted() method on your Vue instance. I just had a similar issue with Vue and jQuery Lazyload and that solved it for me. For example:

var app = new Vue({
    el: ...
    data() ...
    computed: ... 
    methods: ...
    mounted() {
        $("img.lazy").lazyload()
    }
})

0👍

I found many modules on the internet, but I like to avoid modules when I can. So I came up with something else, I don’t know if it’s the best, but it works and I didn’t see any performances loss, I lazy load all the images when the page loads. You may prefer on scroll if you have lots of them, but I guess you’ll figure this out if my answer fits your needs.

You’ll need vueX for this, but I’ll avoid the set up as this is not replying to your question.

If, like me, you have some kind of Index.vue component which main usage is to initiate all the child components (I use to do that for vue-router for instance), place a mounted() function in it :

mounted(){
    const ctx = this;

    // You could use this method, but if you reload the page, the cache of the browser won't allow your JS to trigger .onload method, so better use what's after.
    /*window.onload = function(){
        console.log('page loaded, can load images');
        ctx.$store.dispatch('setPageLoaded', true);
    }*/

    let interval = setInterval(function() {
        if(document.readyState === 'complete') {
            clearInterval(interval);
            ctx.$store.dispatch('setPageLoaded', true);
        }
    }, 100);
}

=> On the page load, I just set a page_load variable in the store to true.

Then, in any component you’d like to lazy load the image, just use 2 computeds (I used a mixin that I include in my components so I avoid repeating some code) :

computed: {
    page_loaded(){
        return this.$store.getters.getPageLoaded;
    },
    image(){
        if(this.page_loaded){
            console.log('starting loading image');

            if(this.product.picture){
                return resizedPicture(this.product.picture, this.width, this.height);
            }else if(this.product.hasOwnProperty('additional_pictures') && this.product.additional_pictures.length){
                return resizedPicture(this.product.additional_pictures[0], this.width, this.height);
            }

            return '';
        }
    }
}

page_loaded() goal is to return the store page_loaded variable I talk about.

image() goal is to actually load the image.

I used that for inline CSS background-image property, so my HTML looks like this :

<span v-if="page_loaded" class="image" :style="'background-image:url('+image+')'" :width="1200" :height="900"></span>

I hope it’ll help, but as I said, feel free guys to tell me if it’s not optimized.

Leave a comment