1.介绍
图片预加载和懒加载都是为了性能问题,那什么是预加载呢,我这边就给大家简单介绍一下。正常情况下,我们在进入一个页面时才会加载该页面中的图片,然后将图片放入缓存中,下次进入该页面就不用加载加载过的图片了,当图片多加载慢时,会有用户体验不佳等问题。当项目需求需要用户进入网站时,比方说进入到首页时,就会自动加载网站中的所有图片,这时候就运用到了图片预加载。

就比如我上面写的一个小例子,当点击About时,才会发送请求加载图片,现在我需要进入这个网页,还在Home中时就开始发送请求加载图片了,下面我就来演示一下如何实现的。
2.Link标签
只需要的在vue项目中的index.html文件中添加一个Link标签,属性rel设置为preload,属性as设置为image,在属性href上放入我的的图片地址。
<link rel="preload" as="image" href="图片地址">
这样我们就可以实现图片的预加载,但这肯定不能满足我的的需求,当有许多张图片时,我们不可能写许多个link标签,这样既费时也费力,因此需要写一个方法。
3.封装方法
只需要封装一个简单方法就能实现,这个方法就是创建link标签,将link标签添加到head标签中。创建一个js文件,我这边取名为preloadImage.js,将方法放在该文件中,然后导出方法,在main.js文件中运行,下面是代码的实现:
preloadImage.js:
const images = [
'https://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1305/16/c4/20990657_1368686545122.jpg',
'https://img.ixintu.com/download/jpg/201911/e25b904bc42a74d7d77aed81e66d772c.jpg!con',
'https://img95.699pic.com/photo/50059/8720.jpg_wh860.jpg',
'https://images.shejidaren.com/wp-content/uploads/2014/07/085628m6c.jpg',
'https://img95.699pic.com/photo/50064/7148.jpg_wh860.jpg',
'https://img95.699pic.com/photo/50067/8224.jpg_wh860.jpg',
'https://seopic.699pic.com/photo/50017/0763.jpg_wh1200.jpg',
'https://pic1.zhimg.com/v2-02760a1bf058904006740d3f66b2c9ac_r.jpg?source=1940ef5c'
]
export async function preloadImage(imgNum = 3) {
const _images = [...images]
function loadImage() {
const src = _images.shift()
return new Promise((res, rej) => {
// 创建link标签
const linkLabel = document.createElement('link')
// 添加对应属性
linkLabel.rel = 'preload'
linkLabel.as = 'image'
linkLabel.href = src
// 将创建的link标签添加到head标签中
document.head.appendChild(linkLabel)
linkLabel.onload = res
linkLabel.onerror = rej
})
}
for (let i = 0; i < imgNum; i++) {
loadImage()
}
}
main.js:
import { createApp } from 'vue'
import App from './App.vue'
import { preloadImage } from './preloadImage'
createApp(App).mount('#app')
preloadImage()
上面方法就实现了图片的预加载,但现在又有一个问题,因为这个方法参数是死的,我这边参数默认值是3,我调用是没有给到参数,因此现在只能预加载3张图片,当然将循环的次数改为images.length是可以的,但浏览器处理并发请求只能一次处理6个,我这边也希望这个浏览器请求图片的数量我也可以控制。这时候可以使用到递归,再写一个方法,也运用到了Promise().finally,这个finally的意思是无论请求和失败都能返回。以下是完整代码:
const images = [
'https://img.pconline.com.cn/images/upload/upc/tx/wallpaper/1305/16/c4/20990657_1368686545122.jpg',
'https://img.ixintu.com/download/jpg/201911/e25b904bc42a74d7d77aed81e66d772c.jpg!con',
'https://img95.699pic.com/photo/50059/8720.jpg_wh860.jpg',
'https://images.shejidaren.com/wp-content/uploads/2014/07/085628m6c.jpg',
'https://img95.699pic.com/photo/50064/7148.jpg_wh860.jpg',
'https://img95.699pic.com/photo/50067/8224.jpg_wh860.jpg',
'https://seopic.699pic.com/photo/50017/0763.jpg_wh1200.jpg',
'https://pic1.zhimg.com/v2-02760a1bf058904006740d3f66b2c9ac_r.jpg?source=1940ef5c'
]
export async function preloadImage(imgNum = 3) {
const _images = [...images]
function loadImage() {
const src = _images.shift()
return new Promise((res, rej) => {
// 创建link标签
const linkLabel = document.createElement('link')
// 添加对应属性
linkLabel.rel = 'preload'
linkLabel.as = 'image'
linkLabel.href = src
// 将创建的link标签添加到head标签中
document.head.appendChild(linkLabel)
linkLabel.onload = res
linkLabel.onerror = rej
})
}
function _loadImage() {
loadImage().finally(() => {
if (_images.length) {
_loadImage()
}
})
}
for (let i = 0; i < imgNum; i++) {
_loadImage()
}
}
给递归设置出口,判断数组的长度,当数组长度为0时,会转换为false。至此这样一个基础的图片预加载的方法就完成了。
结语:
如果觉得这篇文章对你有帮助,可以点赞加关注,我还会与大家继续分享前端有用的知识点。
6682

被折叠的 条评论
为什么被折叠?



