Vue回炉重造之图片加载性能优化(Picture loading performance optimization of Vue Remanufacturing)

前言

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

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

Vue.js
Element UI

优化一:图片加载动画

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

// 图片加载
imgLoad:(src)=>{
  let bgImg = new Image();
  bgImg.src = src; // 获取背景图片的url
  bgImg.onerror = () => {
    console.log("img onerror");
  };
  bgImg.onload = () => {
    // 等背景图片加载成功后 去除loading
    console.log("加载完成");
    return false
  };
},

优化二:图片懒加载

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

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

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

.opacity {animation: 0.3s ani linear;}@keyframes ani {0% {opacity: 0;transform: translateX(-200px);}100% {opacity: 1;transform: translateX(0px);

更多内容请见原文,原文转载自:https://blog.csdn.net/weixin_44519496/article/details/119116745

————————

preface

Image loading optimization plays a vital role in the performance of a website. So we use Vue to operate a wave. remarks

The following optimization I and optimization II columns are encapsulated in Vue’s tool functions, so please read them carefully. Otherwise, it is easy to make mistakes if you copy them directly. resources

Vue.js
Element UI

Optimization 1: image loading animation

The picture can be displayed only after the picture is loaded, and the loading animation ends. We use the loading component in the element UI as the loaded animation. Assume that the initial value of a variable loading is true and false when the picture is loaded.

// 图片加载
imgLoad:(src)=>{
  let bgImg = new Image();
  bgImg.src = src; // 获取背景图片的url
  bgImg.onerror = () => {
    console.log("img onerror");
  };
  bgImg.onload = () => {
    // 等背景图片加载成功后 去除loading
    console.log("加载完成");
    return false
  };
},

Optimization 2: lazy image loading

The picture is requested only when it is in the viewport position. This optimization can be used not only on the home page of the website, but also on pages with more pictures to save performance. Without much to say, let’s realize a wave.

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

You can set the animation name of the class you like here. What I write here is like this. You can refer to it.

.opacity {animation: 0.3s ani linear;}@keyframes ani {0% {opacity: 0;transform: translateX(-200px);}100% {opacity: 1;transform: translateX(0px);

For more information, please refer to the original text, which is reproduced from: https://blog.csdn.net/weixin_44519496/article/details/119116745