为什么需要懒加载?
组件、图片、路由对页面加载速度影响非常大。比如,当一个页面内容比较多的时候,加载速度就会大大的降低,极大的影响到用户体验 。更有甚者,一个页面可能会有几百个图片,但是页面上仅仅只显示前几张图片,那其他的图片是否可以晚点加载用于提高性能。
什么是懒加载?
懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。在 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>
复制代码
评论