Nuxt.js: Proper use of lazy load

Created on 31 Mar 2017  路  10Comments  路  Source: nuxt/nuxt.js

How to use vue-lazyload properly with nuxt?
Nuxt uses ~assets syntax or require('...') method to implement image urls. This means that these two variants both loading images BEFORE vue-lazyload starting its work.
After images all are requested and downloaded by browser vue-lazyload know their urls and start to show them lazily. But it is already make no sense((

How to use vue-lazyload with nuxt or how avoid ~assets or require(...)preloading?

This question is available on Nuxt.js community (#c425)
help-wanted

Most helpful comment

There are several advantages when using webpack's import/require from ~/assets directory, such as adding hash to the filename to enable long term caching, passing images through custom webpack loaders, etc.

Therefore, I suggest not putting all images in ~/static directory, and to answer the original question: just use require inside v-bind with data-src!

For example

use v-bind
<img v-bind:data-src="require('~/assets/images/foo.png')">
or :short-hand
<img :data-src="require('~/assets/images/bar.jpg')">

Because of url-loader, require will return a url.

All 10 comments

a simple way you can put those image to /static/img folder
that will working ...

I tried vue-loader will not require data-srcset='image.jpg' , even sometimes I want require image background in html template ( style attribute )

another way ....

maybe can make a webpack plugin to change src='image.jpg' to data-src='image.jpg' ( or data-srcset ) after vue-loader reqire image ....

obviously I do not understand how to create a plugin ...

so , I put image to static folder ( or CDN ) when I need the pic lazyload ...

@ausir0726 Thank you. I'll try your way.

There are several advantages when using webpack's import/require from ~/assets directory, such as adding hash to the filename to enable long term caching, passing images through custom webpack loaders, etc.

Therefore, I suggest not putting all images in ~/static directory, and to answer the original question: just use require inside v-bind with data-src!

For example

use v-bind
<img v-bind:data-src="require('~/assets/images/foo.png')">
or :short-hand
<img :data-src="require('~/assets/images/bar.jpg')">

Because of url-loader, require will return a url.

It doesn't work for me. I have tried both at assets and static directories.
Static:
<img v-bind:data-src="require('/lucky-barber.png')">
throws:

Cannot find module "/lucky-barber.png"

Assets:
<img v-bind:data-src="require('~/assets/ucky-barber.png')">
It doesn't throw error but it doesn't load the images. The img el in devTools is:
data-src="/_nuxt/img/lucky-barber.74353ad.png"

I'm using:

    "nuxt": "^1.4.0",
    "vue-lazyload": "^1.2.3",

and I load the plugin at:
plugins/vue-lazyload.js
with

import Vue from 'vue';
import VueLazyload from 'vue-lazyload';

Vue.use(VueLazyload);

and in nuxt.config.js:
plugins: [ {src: '~/plugins/vue-lazyload', ssr: false}]

I have also tried adding this at nuxt.config.js under build and in extend:

const vueLoader = config.module.rules.find((rule) => rule.loader === 'vue-loader')
      vueLoader.options.transformToRequire['img'] = ['src', 'data-src'];

Next question will be, how to do this in a for loop that renders components with images. Without lazyloading that was: <img v-bind="{src: imgUrl}" >

Worked for me:

~/plugins/vue-lazyload.js:

import Vue from 'vue';
import VueLazyload from 'vue-lazyload';

Vue.use(VueLazyload);

nuxt.config.js:

...
  plugins: [
    { src: '~/plugins/vue-lazyload', ssr: false }
  ]
...

.vue:

...
<img v-lazy="imageurl" />
...

Where imageurl - bound url from static folder (something like http://domain.com/img.jpg).

@coolemur I don't understand what do you mean with bound url. Let's say we have the image: ./static/example.png? How would you write the <img> el exactly? Note that it has to work with both yarn dev and yarn generate of course

@stavros-liaskos

try this:

<img v-lazy="require('./path/to/img.png')" />

this works in both yarn dev and yarn generate

NOTE: for the path you're entering, it's a relative path.

for example:

src/
    components/
        App.vue
    assets/
        images/
            example.png
// App.vue

<img v-lazy="require('../assets/images/example.png')" />
// or use nuxt alias
<img v-lazy="require('~/assets/images/example.png')" />

@stavros-liaskos

It doesn't work for me. I have tried both at assets and static directories.

Because in your example:

<img v-bind:data-src="require('/lucky-barber.png')">

You start the require from /, which is your system root! (super weird isn't it?)

you have to start the path with ./ for current folder; or ../ for the parent folder, etc.

@DaxChen It worked, now. As you can see on my first post, I have tried that before but I've got no idea why it failed.
The only thing left to answer from my first post then, is how to do that over a v-for loop. Let's say a parent renders children and passes to themimgUrl: '~/assets/images/example.png'.
Parent template:

<foto-frame v-for="(foto, index) in fotos" v-if="fotos.length" v-bind:imgUrl="foto.imgUrl"/>

Foto-frame template:

<!--static works-->
<img v-lazy="require('~/assets/images/example.png')"/>

But dynamicly? I've tried this among others but with no success.

<!--Throws error: Cannot find module '~/assets/images/example.png'. -->
<img v-lazy="require(`${imgUrl}`)"/>

UPDATE:
I don't even know if it is technically possible to do the above with images located in /assets. So, I've just moved them to /static and load them like that:

<img v-lazy="require(`${imgUrl}`)"/>

where imgUrl= example.png
+++ I've got lazyload working
--- I don't have the benefits webpack provide (i.e: I have to compress them beforehand)

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

surmon-china picture surmon-china  路  3Comments

vadimsg picture vadimsg  路  3Comments

uptownhr picture uptownhr  路  3Comments

VincentLoy picture VincentLoy  路  3Comments

jaredreich picture jaredreich  路  3Comments