1.图片懒加载:
让图片随着滚动动态加载,即图片的惰性加载。随着图片盒子进入视口区,在进行图片的记载。
实现方法:
1.滚动监听+scrollTop+offsetTop+innerHeight
实现:滚动距离+可视窗口大小 > 图片元素的位置
2.滚动监听+getBoundingClientRect()
API:getBoundingClientRect() 返回一个矩形对象:left, top, right, bottom, x, y属性都是以视窗左上角来计算的
实现:
let oBounding = el.getBoundingClientRect()
if(0<= oBounding.top && oBounding.top <= offsetHeight){
item.setAttribute('src', item.getAttribute('data-url')
}
//上述两种方法都需要进行滚动监听和计算,所以需要自己适当加上防抖或者节流
3.(推荐)intersectionObserve:
>>IntersectionObserver是一个新兴的api,对一些低版本浏览器的兼容性不好.
调用该监听api可以避免过多的监听触发和计算,对页面性能较友好。
接受两个参数:callback是可见性变化时的回调函数,option是配置对象(可选)。
只需使用callback参数.
- callback函数的参数(entries)是一个数组,每个成员都是一个IntersectionObserverEntry对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,entries数组就会有两个成员。
每个IntersectionObserverEntry对象属性含义如下:
- boundingClientRect:目标元素的矩形区域的信息
- intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
- intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
- rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
- isIntersecting:目标元素是否与视口(或根元素)交叉
- isVisible:并未查阅到相关资料,且经过测试其并不会发生变化
- target:被观察的目标元素,是一个 DOM 节点对象
- time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
》》封装vue自定义图片懒加载指令
Vue.directive('lazy', {
inserted: (el, binding) => {
// 创建监听到的回调函数
const callback=(entries)=>{
// 也可以判断 (entries[0].intersectionRatio>0
if(entries[0].isIntersecting)
{
el.src=binding.value
// 停止监听
observer.unobserve(el)
}
}
//创建监听者实例
const observer = new IntersectionObserver(callback);
observer.observe(el)
}
})
//使用
<img width="100%" v-lazy="imgurl">
2.路由懒加载
官方解释:
- 当打包构建应用时,一个js包会变的非常大,影响单页面页面程序加载。
- 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应的组件,这样就更高效了。
原理:通过require按需赋值,wepack打包的时候就不会将所有的组件打包在同一个js文件中
- require是赋值过程,其实require的结果就是对象、数字、字符串、函数等,再把require的结果赋值给某个变量
- import是解构过程,但是目前所有的引擎都还没有实现import,我们在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require
实现:
将放在文件头部的
import Home from "@/views/home.vue"
改成下列
1. 使用VUE中的异步组件进行懒加载 【require是 AMD规范引入方式】
export default new Router({ routes: [{ path: '/', name: 'HelloWorld', component: resolve => { require(['@/components/HelloWorld'],resovle); } }] }) const Home = () =>import('../components/home.vue')
3、ES6写法 【import是es6的语法标准】
export default new Router({ routes: [{ path: '/', name: 'HelloWorld', component: () =>import('../components/home.vue')} }] })
3.组件懒加载
1.v-if实现懒加载,
当v-if=false时,组件是不会渲染的。但一个个组件添加v-if的繁琐方法也不可取。
- 解决方案:
1.用较大的盒子包裹添加v-if,和定时器或异步操作去懒加载
或者封装成一个懒加载组件添加插槽,定时器<pl-lazy>懒加载内容</pl-lazy>
2.require按需引入
export default { components: { Main, }, data: function(){ return{ Main: ()=>import("@/src/main"), } } }