Vue.js的图片加载性能优化你可以试试
2023-03-20 15:27:19 时间
前言
图片加载优化对于一个网站性能好坏起着至关重要的作用。所以我们使用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);
}
}
整合工具包
我们做Vue脚手架项目时,经常会用到很多重复的代码段或者方法函数,所以我们可以封装起来,想用的时候就用,也避免了代码冗余。
1、在src根目录下创建util文件夹,里面创建util.js;
2、在src根目录下的main.js中键入以下代码,引入util.js,并且全局注册;
import utils from './util/util'
Vue.prototype.$utils=utils
3、编辑util.js;
export default {
// 图片加载
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;
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;
}
}
}
}
实例
我们封装了工具函数,那么我们就使用它,这里使用this.$utils
调用每个方法。
应用:图片加载动画
我们在一个页面这样使用了它,this.bannerSrc
是图片地址,this.loading
是加载动画的状态。
mounted() {
if (!this.$utils.imgLoad(this.bannerSrc)) {
this.loading = false;
}
}
应用:图片懒加载
1、设置keep-alive
的页面
methods: {
// 懒加载图片
scrollView() {
const fn = this.$utils.lazyload.bind(this.$utils);
window.addEventListener("scroll", fn);
// 离开组件
this.$once("hook:deactivated", function() {
window.removeEventListener("scroll", fn);
});
}
},
activated() {
this.scrollView();
},
mounted() {
this.$utils.lazyload(); // 初始化
}
2、未设置keep-alive
的页面
mounted() {
this.$utils.lazyload();
window.addEventListener("scroll", this.$utils.lazyload.bind(this.$utils));
},
beforeDestroy(){
window.removeEventListener("scroll", this.$utils.lazyload.bind(this.$utils));
}
IntersectionObserver
这是h5的api,IntersectionObserver。不过兼容性不好,大家可以试一下。
const io = new IntersectionObserver(dom);
let imgs = document.querySelectorAll('[data-src]');
function dom(entries){
entries.forEach((item) => {
if(item.isIntersecting){
console.log(1)
item.target.src = item.target.dataset.src
io.unobserve(item.target)
}
})
}
imgs.forEach((item)=>{
io.observe(item)
})
结语
作者:「Vam的金豆之路」 主要领域:「前端开发」
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十