在前端的性能优化里面常常提及图片加载优化,实现方案会有雪碧图、图片压缩以及懒加载。所谓图片懒加载,道理同组件懒加载类似,只有当页面需要使用到的时候再去请求图片。
如何实现图片懒加载?
1、使用vue-loayload插件
插件的使用遵循 下载->引入->安装->使用 四个步骤
下载:
npm i vue-lazyload -S
引入和安装:可以在main.js中全局引入,也可以单文件里面局部引入,其实配置项可以参考
import lazyload from 'vue-lazyload';
Vue.use(lazyload, {// 第二个参数表示配置项
loading: require('@/assets/images/common/default.png'),
error: require('@/assets/images/common/default.png'),
})
使用:
<img v-lazy="https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/a4aa0cbfad7de34618c4bebdbdeee4e1.jpg?w=2452&h=920">
貌似在更改图片地址的时候会存在视图不更新的情况,此时可以通过给img元素增加key值解决,尴尬的是我没遇到过~~~
一不小心翻到大佬手写的v-lazyload指令github地址,效果与v-lazy类似,赶紧收藏起来膜拜下,下面自己手写的表示弱爆了呀。
2、手写
听说不喜欢自己造轮子的前端不是好前端,这话我听谁说的呀,捂脸。
实现方案:1、定义中间变量用于存储图片地址;
2、监听容器滚动事件,把图片地址赋给要展示的元素;
3、建议固定容器宽高,避免页面重排(回流),当服务器请求缓慢或请求失败时使用默认图片。
一言不合就喜欢上代码~~~非常不要脸的推荐胡邹邹的码云
<template>
<section class="vh100 oa" @scroll="scroll" ref='sec'>
<ul>
<li v-for="(item, index) in imgList" :key="index">
<img :src="item.imgSrc||defaultImg" @error="doError(item)">
</li>
</ul>
</section>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
interface ImgItem {
imgSrc: string;
imgUrl: any;
}
@Component
export default class PicLazyLoad extends Vue {
private defaultImg: any = require('../../assets/images/common/default.png');
private imgList: ImgItem[] = [
{ imgSrc: '', imgUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/a4aa0cbfad7de34618c4bebdbdeee4e1.jpg?w=2452&h=920'},
{ imgSrc: '', imgUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/fc7c5cc595e12203796678eedd9c4250.jpg?thumb=1&w=1533&h=575&f=webp&q=90'},
{ imgSrc: '', imgUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/e45bcdea59448cd82360662a331409fc.jpg?thumb=1&w=1533&h=575&f=webp&q=90'},
{ imgSrc: '', imgUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/a38b1d56409913d5dc869023ade36d94.jpg?thumb=1&w=1533&h=575&f=webp&q=90'},
{ imgSrc: '', imgUrl: 'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/6bd4174b8c5aad67a64864a5716ad152.jpg?thumb=1&w=1533&h=575&f=webp&q=90'},
];
private imgH: number = 0; // 图片高度
private clientH: number = document.documentElement.clientHeight; // 视口高度
private curImg: number = 0; // 当前展示图片
private created() {
console.warn('图片懒加载,主要用于需要加载大量图片时,优先加载首屏图片,其他屏幕图片滚动加载');
console.warn('优化图片加载失败时使用默认图片');
}
private mounted() {
this.imgH = (document.querySelector('img') as any).getBoundingClientRect().height;
this.curImg = Math.floor(this.clientH / this.imgH);
this.imgList.forEach((item, index) => {
if ( index <= this.curImg ) {
item.imgSrc = item.imgUrl;
}
});
}
private scroll() {
const scrollTop: number = (this.$refs.sec as any).scrollTop;
const acc: number = Math.floor(scrollTop / this.imgH);
setTimeout( () => this.imgList[this.curImg + acc].imgSrc = this.imgList[this.curImg + acc].imgUrl, 500);
}
private doError(item: ImgItem) {
item.imgSrc = '';
}
}
</script>
<style lang="scss" scoped>
img {
width: 153*5px;
height: 57*5px;
}
</style>
ts写的不溜,啥时候能来个人赏个赞指点一下^^,我太难了@_@