性能优化-懒加载(图片 组件 路由)

我心飞翔 分类:vue

为什么需要懒加载?

组件、图片、路由对页面加载速度影响非常大。比如,当一个页面内容比较多的时候,加载速度就会大大的降低,极大的影响到用户体验 。更有甚者,一个页面可能会有几百个图片,但是页面上仅仅只显示前几张图片,那其他的图片是否可以晚点加载用于提高性能。

什么是懒加载?

懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。在vue中组件懒加载又称为代码分割,也叫延迟加载,即在需要的时候进行加载,随用随载。

图片懒加载的实现原理

一张图片就是一个<img>标签,而图片的来源主要是依靠src属性。浏览器是否发起请求根据是否有src属性决定。在没有进到可视区的时候,就不给<img>赋src属性,这样就不会发起请求。下面重点就是对可视区的判断:

网页可见区域:

宽: document.body.clientWidth; 高: document.body.clientHeight;

包括边线的宽: document.body.offsetWidth; 包括边线的高: document.body.offsetHeight ;

网页正文全文:

宽: document.body.scrollWidth; 高: document.body.scrollHeight;

网页被卷去部分:

高: document.body.scrollTop; 左: document.body.scrollLeft;

网页正文部分

上: window.screenTop; 左: window.screenLeft;

屏幕分辨率:

高: window.screen.height; 宽: window.screen.width;

屏幕可用工作区高度: window.screen.availHeight;

了解这些我们先完成HTML的代码部分:

//src存放的是加载图片 data-src存放的才是真正的图片地址

<img src="img/load.png" data-src="img/img.png" />

实现JavaScript部分:

// onload是等所有的资源文件加载完毕以后再绑定事件

//imgs为图片列表

window.onload = function () {

// 获取到浏览器顶部的距离

function getTop(e) {

return e.offsetTop;

}

// 懒加载实现

function lazyload(imgs) {

// 可视区域高度

let h = window.innerHeight;

//滚动区域高度

let s = document.documentElement.scrollTop || document.body.scrollTop;

for (var i = 0; i < imgs.length; i++) {

//图片距离顶部的距离大于可视区域和滚动区域之和时懒加载

if ((h + s) > getTop(imgs[i])) {

// 真实情况是页面开始有2秒空白,所以使用setTimeout定时2s

(function (i) {

setTimeout(function () {

// 不加立即执行函数i会等于9

// 隐形加载图片或其他资源,

//创建一个临时图片,这个图片在内存中不会到页面上去。实现隐形加载

let temp = new Image();

temp.src = imgs[i].getAttribute('data-src'); //只会请求一次

// onload判断图片加载完毕,真是图片加载完毕,再赋值给dom节点

temp.onload = function () {

// 获取自定义属性data-src,用真图片替换假图片

imgs[i].src = imgs[i].getAttribute('data-src')

}

}, 2000)

})(i)

}

}

}

lazyload(imgs);

// 滚屏函数

window.onscroll = function () {

lazyload(imgs);

}

}

现在我们常用的vue也有专属的方式:Vue-Lazyload

路由加载:

为什么要使用组件懒加载?

为给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题。

路由懒加载的实现

     主要方式:resolve => require(['资源路径'], resolve)

具体实现:

//没有使用路由懒加载

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
       routes: [
                 {
                      path: '/',
                      name: 'HelloWorld',
                      component:HelloWorld
                  }
               ]
})

//使用路由懒加载

import Vue from 'vue'
import Router from 'vue-router'
  /* 此处省去之前导入的HelloWorld模块 */
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: resolve=>(require(["@/components/HelloWorld"],resolve))
    }
  ]
})

组件懒加载

相同与路由懒加载

//原来组件中写法

<template>
  <div>
  <One-com></One-com>
  </div>
</template>
<script>
import One from './one'
export default {
  components:{
    "One-com":One
  }
}
</script>

//const方法

<template>
  <div>
  <One-com></One-com>
  </div>
</template>
<script>
import One from './one'
export default {
  components:{
    "One-com":One
  }
}
</script>

//异步方法

<template>
  <div>
  <One-com></One-com>
  </div>
</template>
<script>
export default {
  components:{
    "One-com":resolve=>(['./one'],resolve)
  }
}
</script>

回复

我来回复
  • 暂无回复内容