Vue.js的图片加载性能优化你可以试试

前言

图片加载优化对于一个网站性能好坏起着至关重要的作用。所以我们使用Vue来操作一波。

备注

以下的优化一、优化二栏目都是我自己封装在Vue的工具函数里,所以请认真看完,要不然直接复制的话,容易出错的。

资源

  • Vue.js

  • Element UI

优化一:图片加载动画

只有当图片加载完成后才可以显示图片,加载动画结束。我们使用Element UI中的loading组件来用作加载的动画。假设一个变量loading初始值为true,当图片加载完时为false。

1 // 图片加载 2    imgLoad:(src)=>{ 3      let bgImg = new Image(); 4      bgImg.src = src; // 获取背景图片的url 5      bgImg.onerror = () => { 6        console.log("img onerror"); 7      }; 8      bgImg.onload = () => { 9        // 等背景图片加载成功后 去除loading 10        console.log("加载完成"); 11        return false 12      }; 13    },

优化二:图片懒加载

当图片处于视口位置时,才会请求图片。这个优化不仅可以用在网站首页,还可以用在图片比较多的网页,节约性能。话不多说,我们来实现一波。

1 // 获取图片距离 2    getRect(element) { 3      const rect = element.getBoundingClientRect(); 4      const top = !document.documentElement.clientTop ? document.documentElement.clientTop : 0; 5      const left = !document.documentElement.clientLeft ? document.documentElement.clientLeft : 0; 6      return { 7          top: rect.top - top, 8          bottom: rect.bottom - top, 9          left: rect.left - left, 10          right: rect.right - left 11      } 12    }, 13    // 封装图片懒加载 14    lazyload() { 15      let img = document.getElementsByTagName("img"); 16      let len = img.length; 17      let n = 0; // 存储图片加载到的位置,避免每次都从第一张图片开始遍历 18      // 可见区域高度 19      const seeHeight = window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;  20      for (let i = n; i < len; i++) { 21          // 如果图片距顶部距离小于可见区域高度与滚动条距离顶部高度之和时,才显示图片 22          let rectTop = this.getRect(img[i]).top;      // 这里的this.getRect()是用来获取图片位置的。 23          let rectBottom= this.getRect(img[i]).bottom;  24          if (rectTop > 0 && rectTop < seeHeight && rectBottom > 0 && rectBottom < seeHeight) { // 已经在视口 25              img[i].getAttribute("src") === ""?(img[i].setAttribute('class', 'opacity'),img[i].src = img[i].getAttribute("data-src")):n = i + 1; 26          } else if(rectTop < seeHeight && rectBottom >= seeHeight){ // 正在进入视口 27              img[i].getAttribute("src") === ""?(img[i].setAttribute('class', 'opacity'),img[i].src = img[i].getAttribute("data-src")):n = i + 1; 28          } 29      } 30    }

这里的设置类名opacity可以自己根据喜欢的动画设置。我这里写的是这样的,可以参考一下。

1.opacity { 2  animation: 0.3s ani linear; 3} 4@keyframes ani { 5  0% { 6    opacity: 0; 7    transform: translateX(-200px); 8  } 9  100% { 10    opacity: 1; 11    transform: translateX(0px); 12  } 13} 14

整合工具包

我们做Vue脚手架项目时,经常会用到很多重复的代码段或者方法函数,所以我们可以封装起来,想用的时候就用,也避免了代码冗余。

1、在src根目录下创建util文件夹,里面创建util.js;

2、在src根目录下的main.js中键入以下代码,引入util.js,并且全局注册;

1import utils from './util/util' 2 3Vue.prototype.$utils=utils 4

3、编辑util.js;

1export default { 2    // 图片加载 3    imgLoad:(src)=>{ 4      let bgImg = new Image(); 5      bgImg.src = src; // 获取背景图片的url 6      bgImg.onerror = () => { 7        console.log("img onerror"); 8      }; 9      bgImg.onload = () => { 10        // 等背景图片加载成功后 去除loading 11        console.log("加载完成"); 12        return false 13      }; 14    },  15    // 获取元素距离 16    getRect(element) { 17      const rect = element.getBoundingClientRect(); 18      const top = !document.documentElement.clientTop ? document.documentElement.clientTop : 0; 19      const left = !document.documentElement.clientLeft ? document.documentElement.clientLeft : 0; 20      return { 21          top: rect.top - top, 22          bottom: rect.bottom - top, 23          left: rect.left - left, 24          right: rect.right - left 25      } 26    }, 27    // 封装图片懒加载 28    lazyload() { 29      let img = document.getElementsByTagName("img"); 30      let len = img.length; 31      let n = 0; // 存储图片加载到的位置,避免每次都从第一张图片开始遍历 32      // 可见区域高度 33      const seeHeight = window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;  34      for (let i = n; i < len; i++) { 35          // 如果图片距顶部距离小于可见区域高度与滚动条距离顶部高度之和时,才显示图片 36          let rectTop = this.getRect(img[i]).top; 37          let rectBottom= this.getRect(img[i]).bottom; 38          if (rectTop > 0 && rectTop < seeHeight && rectBottom > 0 && rectBottom < seeHeight) { 39              img[i].getAttribute("src") === ""?(img[i].setAttribute('class', 'opacity'),img[i].src = img[i].getAttribute("data-src")):n = i + 1; 40          } else if(rectTop < seeHeight && rectBottom >= seeHeight){ 41              img[i].getAttribute("src") === ""?(img[i].setAttribute('class', 'opacity'),img[i].src = img[i].getAttribute("data-src")):n = i + 1; 42          } 43      } 44    } 45} 46

实例

我们封装了工具函数,那么我们就使用它,这里使用this.$utils调用每个方法。

应用:图片加载动画

我们在一个页面这样使用了它,this.bannerSrc是图片地址,this.loading是加载动画的状态。

1 mounted() { 2    if (!this.$utils.imgLoad(this.bannerSrc)) { 3      this.loading = false; 4    } 5  }

应用:图片懒加载

1、设置keep-alive的页面

1methods: { 2    // 懒加载图片 3    scrollView() { 4      const fn = this.$utils.lazyload.bind(this.$utils); 5      window.addEventListener("scroll", fn); 6      // 离开组件 7      this.$once("hook:deactivated", function() { 8        window.removeEventListener("scroll", fn); 9      }); 10    } 11  }, 12  activated() { 13    this.scrollView(); 14  }, 15  mounted() { 16     this.$utils.lazyload(); // 初始化 17  }

2、未设置keep-alive的页面

1 mounted() { 2    this.$utils.lazyload(); 3    window.addEventListener("scroll", this.$utils.lazyload.bind(this.$utils)); 4  }, 5  beforeDestroy(){ 6    window.removeEventListener("scroll", this.$utils.lazyload.bind(this.$utils)); 7  }

IntersectionObserver

这是h5的api,IntersectionObserver。不过兼容性不好,大家可以试一下。

1const io = new IntersectionObserver(dom); 2 let imgs = document.querySelectorAll('[data-src]'); 3 function dom(entries){ 4  entries.forEach((item) => { 5   if(item.isIntersecting){ 6        console.log(1) 7    item.target.src = item.target.dataset.src  8    io.unobserve(item.target)  9   } 10    11  }) 12 }  13 imgs.forEach((item)=>{ 14  io.observe(item) 15 }) 16

结语

如果觉得有用,不妨关注一下哦~

❝

作者:「Vam的金豆之路」

主要领域:「前端开发」

我的微信:「maomin9761」

微信公众号:「前端历劫之路」

❞

本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/y0fz8d-9P12cW3F8QQLzXA,如有侵权,请联系删除。

点赞
收藏

评论区

加载中...

相关推荐

前端性能优化

前端性能优化1、减少资源的请求次数和大小压缩合并js和css文件,减少http请求次数和请求资源的大小;在项目中使用webpackglup等打包编译工具2、尽量使用字体图标或者svg图标代替传统的png(jpg)图渲染更快,减少代码体积,且放大不会出现变形等3、使用图片懒加载目的是减少页面第一次加载的http请求次数,实现思路:

聊聊前端性能优化

为什么要做性能优化?性能优化有多重要?网站的性能对于用户的留存率、转化率有很大的影响,直白的说,提高网站的性能可以直接提高网站带来的收益。性能优化的分类前端的性能优化主要分为两类:1.加载时优化;2.运行时优化;例如压缩文件、使用CDN加载静态资源属于加载时优化;及时的解绑事件、减少DOM的操作属于运行时优化。吉

前端性能优化

为什么要做性能优化?性能优化有多重要?网站的性能对于用户的留存率、转化率有很大的影响,直白的说,提高网站的性能可以直接提高网站带来的收益。性能优化的分类前端的性能优化主要分为两类:1.加载时优化;2.运行时优化;例如压缩文件、使用CDN加载静态资源属于加载时优化;及时的解绑事件、减少DOM的操作属于运行时优化。吉

【Flutter实战】图片和Icon

3.5图片及ICON3.5.1图片Flutter中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。ImageProviderImageProvider是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvi

Egret白鹭开发小游戏之自定义load加载界面

刚接触不久就遇到困难自定义loading。想和其他获取图片方式一样获取加载界面的图片,结果发现资源还没加载就需要图片,在网上百度了许多,都没有找到正确的方式,通过自己的摸索,终于,,,我成功了。。。下面介绍一下主要思想:首先,我们需要使用异步加载的方式,在加载界面之前加载loading界面需要的素材,然后再loadingUI中就可以大胆使

6 招教你提高网站速度

!图片1(https://image.evget.com//Content/files/2017/7/28/5174b527782a4fcca1e997eba85dfe89636368468467682067.gif)①图片优化统计数据显示,用户倾向于放弃一个在3秒内未加载完成的网页。由于加载图片占据了网页上可下载的大部分字节空间,所以

Vue.js的图片加载性能优化你可以试试 - HelloWorld