Web页面图片预加载方案

现象

在开发活动时,有一个转盘抽奖的功能,要求抽到每个奖项的时候显示不同的图片,我们内心是这样想的;

然而现实却是这样,图片去哪里了啊,原来是图片比较大(之前没有做优化)加载比较慢,所以我们看到了文本,但是没有看到背景。

因为红包组件是动态替换背景图片的,所以图片没有缓存时,都需要立即发请求,所以就导致了加载慢的问题;

示例代码:​

<div className={'redpack-content ' + (show ? 'animated bounceIn' : 'redpack-hidden')}
     style={{backgroundImage: 'url("' + imgArr[level] + '")'}}>
     <div className="redpack-text center">
        {textArr[level]}
     </div>
     <div className="redpack-x">
        <img onClick={this.closeClick} src={require('../../../images/homev2/redpackage/x.png')}/>
     </div>
</div>

每次按照奖项的index来获取数组中存储的图片****。

原理

图片资源下载一次后,第二次就会从缓存取。
下载图片和网络有很大的关系,尤其是国外的服务器,在缓存取的时候和网络没有关系,是很快的。
但是有一个条件:服务器必须设置浏览器可缓存,否则预加载没有任何意义,因为每次都会去服务器拉取最新的资源。

实现

在页面加载完成时,或者setTimeout加载所需的图片,示例代码

//  预加载图片
//  这里每次加载5个图片,每一批间隔是1s
const preLoadConfig = {size: 5, interval: 1000};
const preLoadImage = (imageArr = []) => {
    //  如果没有图片直接返回
    if (!imageArr.length) {
        return
    }
    setTimeout(function () {
        imageArr.splice(0, preLoadConfig.size).forEach(item => {
            let img = new Image();
            img.src = item
        });
        preLoadImage(imageArr)
    }, preLoadConfig.interval)
};
  
//  开始加载图片,这个应该放在页面的入口处
preLoadImage([
    require('../../../images/homev2/redpackage/thank.png'),
    require('../../../images/homev2/redpackage/2p.png'),
    require('../../../images/homev2/redpackage/1p.png'),
    require('../../../images/homev2/redpackage/10g.png'),
    require('../../../images/homev2/redpackage/15g.png'),
    require('../../../images/homev2/redpackage/3g.png'),
    require('../../../images/homev2/redpackage/80g.png'),
    require('../../../images/homev2/redpackage/5g.png')
])

延迟一秒获取剩余的图片,防止和其他的请求一起,导致请求阻塞(浏览器有同源请求上限)。

new Image()创建对象,指定src的时候会下载指定的图片,等下次请求的时候就是 from disk 或者 from memory 了,速度显然快了很多

优化结果

不废话,看效果(页面首次加载时)

抽中红包后一看,这个文件仅仅花了6ms,简直无法感知。

到这里,你也许看完了,文中有问题的请帮我指正,谢谢阅读。

在使用图片之前处理下图片也可以加快加载速度,查看这里:Web页面中PNG图片优化

留下回复