Nuxt Lazy Load Image

September 27, 2020
vue-lazyload

native lazy loading

The easiest way is to use native lazy loading, which is currently supported by Edge, Chrome and Opera.

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

Load-in distance threshold # All images and iframes that are above the fold—that is, immediately viewable without scrolling—load normally. Those that are far below the device viewport are only fetched when the user scrolls near them.

The distance threshold is not fixed and varies depending on several factors:

  • The type of resource being fetched (image or iframe)
  • Whether Lite mode is enabled on Chrome for Android
  • The effective connection type

Image loading # To prevent the surrounding content from reflowing when a lazy-loaded image is downloaded, make sure to add height and width attributes to the element or specify their values directly in an inline style:

Images will still lazy-load if dimensions are not included, but specifying them decreases the chance of browser reflow.

I am using Bootstrap Grid System to load the images on Chrome Version 80.0.3987.106 (Official Build) (64-bit) (Ubuntu) with two observations

  • Lazy load seems to work only I if specified width and height (maybe is due to the Grid System)
  • Lazy load only happend on very far distance from viewport. Assuming the viewport is 1 page of height, images on the 3rd page still get loaded.

vue-lazyload

vue-lazyload

Install

npm i vue-lazyload

Edit nuxt.config.js.

export default {
  plugins: [
    '~/plugins/vue-lazyload'
  ]
}

Edit plugins/vue-lazyload.js.

import Vue from "vue"
import VueLazyload from "vue-lazyload"

Vue.use(VueLazyload, {
    preLoad: 1.3,
    // attempt: 1,
    loading: '/img/placeholder.svg'
});

Usage in component

<template>
  <div>
    <img v-lazy="srcUrl" :src="placeholderUrl" alt=" " />
  </div>
</template>
<script>
export default {
  computed: {
    srcUrl() {
      return '/img/sample.png'
    },
    placeholderUrl() {
      return '/img/placeholder.svg'
    },
  }
}
</script>

NOTE: src placeholder image is required to avoid nuxt ssr from showing a broken image.

BootstrapVue

If you are already using BootstrapVue, you can use b-img-lazy.

<template>
  <div>
    <b-img-lazy v-for="index in 10" :key="index"
      :show="index <= 3" 
      :src="//via.placeholder.com/300?text=Hello" 
      :blank-src="//via.placeholder.com/300" 
        />
  </div>
</template>
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.