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图片优化