前言
关于【SSD系列】:
前端一些有意思的内容,旨在3-10分钟里, 500-1500字,有所获,又不为所累。
某天,发现有背景图片的弹出框,会出现闪白现象,这,兄弟们,你们说能忍么?
答案:不能!
思路
思路嘛,无非三种
-
弹框时或者显示时,背景图片已经ready
-
背景色或者小图,先顶着,大背景图ready后切换
-
尽可能的快
这里暂且不考虑缓存,因为你无论如何逃不过第一次加载。
方案
可以到 背景图片闪现空白解决方案 看到各种方案演示。
为了提升大家兴趣,先看个png, jpg渐进和png交错的加载效果动图:
方便移动端观看,列一个演示清单:
- 背景图片闪现空白方案-base背景图片
- 背景图片闪现空白方案-preferch
- 背景图片闪现空白方案-创建隐藏Img节点
- 背景图片闪现空白方案-等待图片加载完毕再显示弹框
- 背景图片闪现空白方案-同时设置背景颜色和图片
- png正常,png交错,jpg渐进
方案1 base64
如果背景图片相对小,或者你执意要这嘛做,图片转为bas464,存到css或者html里面。
演示: 背景图片闪现空白方案-base背景图片
不足: base64增加带宽成本,内容会比原本大至少1/3。 至于为什么可参见 前端Base64编码知识,一文打尽,探索起源,追求真相。
方案2 prefetch
<link rel="prefetch" ></link>
<link rel="prefetch" href="./img/bg-huoluo.jpg"/>
.bg {
background-image:url("./img/bg-huoluo.jpg");
background-size: contain;
}
prefetch是对浏览器的暗示,暗示将来可能需要某些资源,但由浏览器决定是否加载以及什么时候加载这些资源。 优先级低。
pre家族:preload, prefetch, dns-prefetch, preconnect, prerender。
有人可能会问,干嘛不用preload。 呵呵, 你说呢?
演示: 背景图片闪现空白方案-preferch
方案3 创建隐藏Img节点
<img src="./img/bg-huoluo.jpg" alt="" title="" style="display: none"/>
.bg {
background-color: #2D2C27;
background-image: url(./img/bg-huoluo.jpg);
background-size: contain;
}
这方案好理解,图片已经请求下载啦。 其实不能解决首屏背景图片的问题。
演示:背景图片闪现空白方案-创建隐藏Img节点
方案4 等待图片加载完毕再显示弹框
let dg = null;
function createDialog() {
onImageLoad('./img/bg-huoluo.jpg').then(src => {
if (!dg) {
dg = document.createElement('div');
dg.className = "bg";
dg.style.backgroundImage = `url(${src})`;
dg.id = "dialog";
dg.innerHTML = `
<div class="content">我爱赫萝!!!!</div> `
document.body.appendChild(dg);
}
})
}
function onImageLoad(src) {
return new Promise((resolve, reject) => {
let img = new Image();
img.src = src;
img.onload = function () {
resolve(src)
}
img.onerror = reject
})
}
当然这是有明显问题的,你不能因为一个背景图片而让内容无法正常展现。
当然你可以有修正方案。
演示: 背景图片闪现空白方案-等待图片加载完毕再显示弹框
方案5 同时设置背景颜色和图片
.bg {
background-color:#433F34;
background-size: contain;
}
.bg-new{
background-image: url(./img/bg-huoluo.jpg)
}
这样,背景图片加载上的时候,不会有明显的闪白效果。 当然要是背景图片,五颜六色,估计有点为难客官啦。
方案6 jpg使用渐进模式,png使用交错模式
这两种模式共同的作用就是,你不必完整的下载完毕图片,就可以看到图片的内容了。
打个比方, 1M的图片,你可能只需下载不到100Kb,就已经能相对清晰的看到图片了。
方案7 小图过度方案
显示loading图片或者小图,完毕后再换大图。 这种方案常用语封面,商品图标等等场景,背景图也可以借鉴其思路。
其他可参考方案
- svg替换图片
- webp格式,减少图片大小
- css spirte, 减少http开销,同时让其早被加载
css spirte + prefech 可以秀一波 - jpg格式图片压缩
- 图片cdn
- 多域名
- 背景图片切割,能repeat就repeat
小结
是不是很简单,一切都看起来没那么难,这样,你才容易入坑啊。
写在最后
写作不易,你的一赞一评就是我前行的最大动力。
技术交流群请到这里来。