提示:本文写于 2013 年,文中涉及的图片加载方式、浏览器行为及代码均基于当时的 Web 开发环境,请结合文章发布时间阅读。
在一些图片搜索网站,比如 Google,我们经常可以看到这样的效果:
当我们搜索并查看一张图片时,刚开始图片可能看起来比较模糊,等一会儿之后,图片又逐渐变得清晰。那么,这个效果究竟是怎么实现的呢?
一开始,我想到的是,在服务器传送图片的时候,能不能使用类似在线播放视频那样的流媒体技术,先把图片的模糊信息传送过来,然后再传送剩余的信息。
实际上,这个想法并不成立。
第一,浏览器在加载图片的时候,本身就是不断接收服务器传送过来的数据。特别是在加载比较大的图片时,可以明显看到图片逐渐被加载完成,这本身就属于一种连续的数据传输过程。
第二,即使服务器能够先把一部分模糊的数据传送过来,浏览器已经把这部分数据加载并显示出来,那么后面的清晰数据传过来以后,又该怎么把原来的内容覆盖掉呢?
显然,仅仅通过这种方式并不能很好地实现我们想要的效果。
虽然这个想法不可行,但也给了我一些提示:
能不能把模糊的数据和清晰的数据分开?
也就是说,刚开始请求模糊的图片,过一段时间之后,再请求清晰的图片。
干脆准备两张图片:
一张模糊的小图,一张清晰的大图。
浏览器默认先加载模糊的小图,等小图加载完成之后,再去加载清晰的大图。
这个原理和之前的一篇博文网页图片延时加载技术是一样的。
如何让图片变模糊?
让图片变模糊主要有两种方法。
第一种是不改变图片尺寸,只降低图片的质量。
第二种是把图片按照原图比例缩小,然后在网页中通过样式把图片重新指定为原来的显示尺寸。
个人比较推荐第二种方法。
下面是一个简单的实现代码:
<!DOCTYPE HTML>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>图片由模糊到清晰的过渡效果</title>
<style>
* {
margin: 0;
padding: 0;
}
img {
width: 1000px;
height: 627px;
margin: 10px auto;
display: block;
}
</style>
</head>
<body>
<img src="small.jpg" alt="小图" originaldata="big.jpg">
<script>
var small = document.getElementsByTagName("img")[0];
// 当图片加载成功之后
small.onload = function(){
setTimeout(function(){
small.src =
small.getAttribute("originaldata") +
"?" +
Math.random();
// Math.random() 用来避免浏览器使用当前图片缓存
// 实际项目中应该删除
}, 3000);
};
</script>
</body>
</html>
代码的原理其实很简单。
首先:
<img src="small.jpg" alt="小图" originaldata="big.jpg">
浏览器先加载 small.jpg。
由于 small.jpg 是一张尺寸比较小的图片,因此加载速度比较快。
等小图加载完成之后,通过:
small.onload
监听图片加载完成事件。然后等待 3 秒:
setTimeout(function(){
...
}, 3000);再把图片的 src 修改为真正的大图:
small.src =small.getAttribute("originaldata");这样浏览器就会开始加载清晰的大图。
所以整个过程可以理解为:
这样就实现了图片从模糊到清晰的过渡效果。
这种方法有什么好处?
这样做的好处主要有两个。
第一,可以节省服务器资源。
很多用户可能只在这个页面停留很短的一段时间,甚至还没有等大图加载完成就离开了。
这种情况下,提前加载一张很大的图片其实没有太大意义。
而先加载一张很小的图片,可以让页面尽快显示内容,只有真正继续停留并需要查看图片的用户,才会继续加载真正的大图。
第二,可以改善用户体验。
大图片加载通常比较慢,如果直接让用户等待一张空白的图片,会让人不知道服务器到底有没有正常工作。
而先显示一张模糊的小图,可以让用户知道:
图片正在加载,只需要等待一会儿就可以看到清晰的图片。
真正需要这些资源的用户,通常也不会太在意这段短暂的等待。
评论0
欢迎分享你的看法,也欢迎补充不同的实践经验。