Lazyload Images with Nuxt/Prismic as a Custom Vue-Directive

Hey Prismic! :wave:

I am running into an issue with vanilla lazyload and Nuxt in a Prismic environment.. though I am not entirely certain if it is prismic or not.

Basically to be as brief as possible - I am using the Prismic/Nuxt blog starter (from github) which works great and want my images to load "lazyily" (err.. lazy?). I am using the vanilla lazyload library :point_right: GitHub - verlok/vanilla-lazyload: LazyLoad is a lightweight, flexible script that speeds up your website by deferring the loading of your below-the-fold images, backgrounds, videos, iframes and scripts to when they will enter the viewport. Written in plain "vanilla" JavaScript, it leverages IntersectionObserver, supports responsive images and enables native lazy loading.

To do this I can creating a custom Vue-Directive and then passing that directive into a prismic-image with v-lazy:

lazyloader.js

import Vue from 'vue'
import LazyLoad from 'vanilla-lazyload'

/*
** Here we are creating a custom
** Vue directive with lazyload `v-lazy`
*/
Vue.directive('lazy', {
  // When the bound element is inserted into the DOM...
  inserted (el) {},
  bind (el) {
    // Array/nodelist
    el.item = []
    el.item.push(el)
    el.instance = new LazyLoad(
      {
        thresholds: `${window.innerHeight * 2}px 0%`
      },
      el.item
    )
  },

  unbind (el) {
    el.instance.destroy()
  }
})

And here is my ImageSlice.vue (with v-lazy)

<template>
...
	<div class="block-img" :class="size">
		<div class="image-cover">
	     	<prismic-image v-lazy :field="img" :alt="img.alt" />
	  	</div>
	</div>
...
</template>

Also as a plugin in my nuxt.config

export default {
...
  /*
  ** Plugins to load before mounting the App
  */
  plugins: [
    {
      src: '~/plugins/lazyloader.js', mode: 'client'
    }
  ],
...
}

The problem is that within my development environment, the images seem to get randomly suck with data-status=loaded or data-status=loading (seems to be random upon page refresh) and I cannot figure out why despite looking into the issue over the past three days or so. I feel it may be an issue with how I have my Vue-Directive set up.. However I have thought it may also be an issue within development mode and I have not generated the app yet using Nuxt Generate. Lazyload does seem to be working at least, but I need some addition feedback on the prismic side of things. Could this be an issue with how Prismic loads images alongside using Lazyload?

I also submitted an support/question issue on the lazyload repo here :point_right: Lazyload with Nuxt as a Vue-Directive · Issue #458 · verlok/vanilla-lazyload · GitHub

Perhaps you guys can just recommend the best way to lazyload images with Prismic within Nuxt :smile:

Thank you!

Hi Rylan,

I’ll be happy to help.

I’m not familiar with this plugin, but it might have something to do with how the images are coming pre-optimized from our imgix integration.

Although there’s no need to use vanilla-lazyload as you can do lazyloading with Imgix and the lazysizes plugin.

This article explains how to do so.

But essentially to set this up you just need to

  1. Install the plugin
  2. Use srcsets for your images
  3. Add the lazyload class

Let me know if this helps.

Thanks.

Hey Phil!

Thanks for getting back to me so soon with that…

This might sound bad, but how do I use srcset when the Prismic-image tag does not provide a src attribute, but rather a :field that binds to the image url?

I’ll go ahead and try out that library and see if it that works better!

Hey Phil!

I actually got the custom vue-directive to work! Woo! I just had to pass in use_native as an option within my lazyloader.js set up. Thanks for the help with everything though:)

I may come back to ask more questions about Nuxt with Prismic!

Best,
Rylan Harper