图片预加载和懒加载

298 阅读2分钟

图片预加载

图片预加载就是在网页全部加载之前,提前加载图片。即在图片被浏览器请求之前,提前将图片文件下载到本地,放到内存中或者缓存中。

实现方法

CSS(background)、JS(Image)、HTML(< img />)

常用的是new Image();,设置其src来实现预载,再使用onload方法回调预载完成事件。

vue实现

1、自定义指令

//定义预载指令
Vue.directive('preload', {
    bind: function (el, binding) {
        let img = new Image()
        img.src = binding.value
        img.onload = function () {
            el.src = binding.value
        }
    }
})

//使用预载指令
<img v-preload="'图片链接'" alt="图片描述" />

在上述代码中,我们通过Vue.directive()方法来定义一个名为preload的指令,该指令绑定在img元素上面。当img元素加载时,预载指令就会触发,创建一个新的Image对象并将图片链接指向预载指令的参数。当该图片加载完成后,将图片链接绑定到img元素的src属性上。这样当img元素的 src属性 发生变化时,图片就能够展示出来了。

图片懒加载

延迟加载

实现方法

第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟,如果用户在加载前就离开了页面,那么就不会加载。

第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载。

第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载,这样能保证用户拉下时正好能看到图片。

1、 使用Intersection Observer API

<template>
  <div>
    <img ref="image" :src="loadingSrc" alt="Lazy loaded image">
  </div>
</template>
<script>
export default {
  data() {
    return {
      loadingSrc: 'path/to/loading.gif', // 图片加载中显示的图片
      imageSrc: 'path/to/image.jpg', // 图片的路径
    };
  },
  mounted() {
    const options = {
      root: null, // 默认为视窗
      rootMargin: '0px',
      threshold: 0.1 // 图片进入视窗的百分比
    };
    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          this.loadImage();
          observer.unobserve(entry.target); // 停止监听
        }
      });
    }, options);
    observer.observe(this.$refs.image);
  },
  methods: {
    loadImage() {
      const image = new Image();
      image.src = this.imageSrc;
      image.onload = () => {
        this.$refs.image.src = this.imageSrc;
      };
    }
  }
};
</script>

这样,当图片进入视窗的10%时,Intersection Observer会触发回调函数,然后加载图片。

2、使用vue-lazyload插件进行懒加载

//安装vue-lazyload插件
npm install vue-lazyload --save

//在main.js中引入并安装Vue.use()
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload)

//在组件中使用
<img v-lazy="'图片链接'" alt="图片描述" />