How to preload images using Vue.js?

Edi picture Edi · Jan 4, 2018 · Viewed 18.3k times · Source

I have a small app using Vue.Js (with webpack). I have a transition section. When the user clicks to a button the content going to change. It's a simple DIV element with an IMG child element. My problem is when the user clicks the button, the next image will be loaded in real-time and it's slow, so somehow I need to preload these images.

I have tried different approaches but couldn't achive the images be preloaded. The problems:

  • Only the first image is the part of the DOM, when page displayed, so the other images will be not loaded. Ok, it's the normal behavior.

  • I couldn't preload the images by using a simple for-loop on an array of images (Preloading images with JavaScript), because images will be requested by a unique query string (1) to each request. So the preloaded image names will not match with the requested.

  • I tried to load the images using require() and bind it to the IMG tag's src property. It's also not solved my problem, the images will be loaded in real-time after the click when the new DIV will be inserted into the DOM.

My simplified single file compontent (.vue) looks something like that:

<template>
    <!-- [FIRST] -->
    <div v-if="contentId == 0">
      <transition
        enter-active-class="animated fadeIn"
        leave-active-class="animated fadeOut"
        mode="out-in">
        <img :src="images.firstScreenShot" key="firstImage">
      </transition>
    </div>
    <!-- [/FIRST] -->

    <!-- [SECOND] -->
    <div v-else-if="contentId == 1">
      <transition
        enter-active-class="animated fadeIn"
        leave-active-class="animated fadeOut"
        mode="out-in">

        <img :src="images.secondScreenShot" key="secondImage">
      </transition>
    </div>
    <!-- [/SECOND] -->
</template>
<script>
    export default {
        data() {
            return {
                contentId: 0,
                images: {
                    firstScreenShot: require('./assets/first-screen-shot.png'),
                    secondScreenShot: require('./assets/second-screen-shot.png'),
                }
            }
        }
    }
</script>

I'm new to Vue.js, maybe my approach is not good. Please let me know what is the good approach!

Answer

Stephan-v picture Stephan-v · Jan 4, 2018

I quickly tried this out in the browser but it seems to work in console. You can use the Javascript Image object to pre-load images it seems:

https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image

You can create a new Image object like so:

const image = new Image();

Then you can assign a src value to that image:

image.src = 'test.jpg'

When you supply the src property with data immediately a network request will be fired by the browser which should be sufficient for the image to be loaded and cached. This way you don't have to insert these images into the DOM.

Someone correct me if I am wrong on this though, haven't tried to out fully.