vue实现图片预加载

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。至此这样一个基础的图片预加载的方法就完成了。

结语:

        如果觉得这篇文章对你有帮助,可以点赞加关注,我还会与大家继续分享前端有用的知识点。

### Vue 实现图片预加载方法 #### 创建 Vue 组件并实现单张图片预加载功能 为了在 Vue 应用程序中实现图片预加载,可以通过创建一个新的组件来处理这个逻辑。该组件内部使用 JavaScript 的 `Image()` 对象来进行实际的图片加载操作[^1]。 ```javascript export default { data() { return { isLoaded: false, imageUrl: 'path/to/your/image.jpg' }; }, methods: { preloadImg(url) { const img = new Image(); img.src = url; if (img.complete) { this.isLoaded = true; // 如果图片已经存在于浏览器缓存,则立即设置状态为已加载完成 } else { img.onload = () => { this.isLoaded = true; // 当图片成功加载完成后更新状态 }; } } }, mounted() { this.preloadImg(this.imageUrl); } }; ``` #### 多张图片预加载及进度跟踪 对于多个图片的同时预加载需求,可以在上述基础上进一步扩展,通过维护一个数组存储待加载的图片链接列表,并记录每一张图片的状态以便追踪整体加载进度[^3]。 ```html <template> <div v-if="loadingProgress !== totalImages">Loading...</div> <!-- 或者展示骨架屏 --> </template> <script> export default { data() { return { imagesUrls: ['image1.jpg', 'image2.png'], loadingProgress: 0, totalImages: 2 }; }, methods: { preloadMultipleImgs(urls) { urls.forEach((url, index) => { let img = new Image(); img.src = url; img.onload = () => { this.loadingProgress += 1; if (this.loadingProgress === this.totalImages) { console.log('All images loaded'); } }; }); } }, mounted() { this.preloadMultipleImgs(this.imagesUrls); } } </script> ``` #### 添加过渡效果提升用户体验 为了让用户有更好的视觉体验,在图片完全加载之前可以用占位符代替真实内容;一旦图片准备好了再平滑切换至最终版本。这通常涉及到 CSS 动画的应用[^4]。 ```css @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .fade-in { animation: fadeIn 0.6s ease-in; } ``` ```html <img :src="isLoaded ? imageUrl : placeholderUrl" class="placeholder-image" :class="{ 'fade-in': isLoaded }"/> ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值