浅析图片懒加载技术
- 出现的背景
图片懒加载是一种网页优化技术。图片作为一种网络资源,在被请求时也与普通静态资源一样,将占用网络资源,而一次性将整个页面的所有图片加载完,将大大增加页面的首屏加载时间。为了解决这种问题,通过前后端配合,使图片仅在浏览器当前视窗内出现时才加载该图片,达到减少首屏图片请求数的技术就被称为“图片懒加载”。 - 传统的解决方案
我们先来探讨一下传统的图片懒加载技术是如何实现的。
以京东sale活动页为例,我们随便选取一个活动地址,查看网页源代码,我们可以找到形如这种结构的img标签:
<img class="J_imgLazyload"
src="//img14.360buyimg.com/cms/g10/M00/13/04/rBEQWFFj4PUIAAAAAAAESxyqJLUAADvdAIHC9oAAARj186.gif"
original="//img11.360buyimg.com/cms/jfs/t12118/41/1394617476/43413/2253395a/5a1f7569N63f38100.jpg" />
我们试着来分析一下这个img标签的结构,首先我们在浏览器中直接打开该img标签的src,即:“//img14.360buyimg.com/cms/g10/M00/13/04/rBEQWFFj4PUIAAAAAAAESxyqJLUAADvdAIHC9oAAARj186.gif”。结果发现这张图是一张10*10的空白图片。我们发现img标签中还有一个伪属性original,里面也有一个很像是图片的链接,我们再在浏览器中访问这个链接:
果然如我们所料,original中存放的才是真实图片的路径。
那么浏览器是怎么加载存放在伪属性中的真实图片的呢?
首先后端直出的页面结构中,img标签中的src为一张占位图,真实图片地址存放在一个伪属性中,如:data-src中。当页面滚动时,遍历当前页面需要进行懒加载的图片,判断图片是否在可视区域内,如果在的话,则取存放在伪属性中的真实src替换当前的src。
以上是一张简略的示意图,外部黑色框代表页面范围(即html的范围),虚线内代表浏览器当前视窗区域。在这个场景下,只有第4、5、6张图片处在当前视窗中,因此它们会使用上述加载策略,使用真实src替换占位图。而其余的几张图片由于并不在可视区域内,因此并不会被立即加载,只有当滚动事件产生,某张图片(或图片的一部分)开始出现在视窗内时,才会真正加载。
-
可优化的一些点:
(1)滚动函数的节流
浏览器中的滚动事件是一个触发非常频繁的事件,有时候我们主观体验只是轻轻拨动了一下滚轮,但实际上触发了数次甚至数十次的onscroll事件:
还记得我们在前文所述的懒加载策略中提到,每次滚动事件都将执行:选择页面所有图片→遍历→筛选在当前视窗内的图片→使用真实src替换占位图。以上过程是一个非常耗时的过程,尤其是在筛选符合条件的图片的步骤。因此,我们需要对滚动事件进行节流:只有当后一次触发滚动与前一次触发滚动的时间间隔大于一定阈值时,才认为这次滚动生效。
(2)预加载
可以看到,虽然当前视窗中只有3张图片,但若使用预加载,将提前加载前后各1屏幕内的图像(红色虚线内),如此一来,当用户在当前视窗内继续上滑或下滑时,该屏内的图片已经提前加载完毕,用户就不会感知到图片从白屏到显像的这种抖动过程,大大提升了用户体验。
4、更优的用户体验
在国内网站中,知乎官网在图片懒加载部分做得较为领先,拥有很好的用户体验。让我们先来看一下效果,随便打开一个知乎问答页(在PC环境中打开):知乎问答页示例
仔细观察,我们可以看到这样一种效果:图片在由白至清晰的过程中有一种模糊渐变的效果,相比于直接替换空白占位图的方案,这种方式不会给用户带来突兀感。
查看页面源代码,我们发现直出的页面中img标签是以这种形式存在的:
img标签及其内的信息作为字符串保存在noscript标签中,src中为一张低品质图片,data-original中为真实图片地址,同时有一个占位的span元素。当页面滚动到该noscript标签对应的位置时,解析出noscript标签中的img,并替换占位span元素:
此时将先加载低质量的小图,再加载清晰的高质量原图:
如此一来,用户将在极短的时间内就能看到图片的大致轮廓。随后等真实图片加载完毕后,再使用CSS控制图片逐渐变清晰,整个过程顺畅自然,一气呵成。在网速较差的环境下,这种方式也能有很优雅的降级体验。
转自前端大全
http://mp.weixin.qq.com/s/JYglEGYN9tnGpDg7ARPx7w