预加载和懒加载是两种加载资源的方式,适用于不同场景。常见的是图片的预加载和懒加载,最近开发组件库,图片组件就用到了预加载和懒加载,记录一下实现方式和相关知识点。
预加载
预加载就是预先加载资源,在使用时就不需要再加载。比如预先加载图片,显示图片时直接从缓存读取不需要再发出网络请求了。
那预加载是怎么实现的呢?我们可以使用Image元素构造器。
|
|
在使用图片之前,创建一个Image实例,并给实例的src实行赋值就可以请求图片。
我们还可以使用纯CSS或者Ajax实现预加载。
预加载的好处是提前加载,用户操作过程中响应更快。但是在一些场景下会牺牲服务器性能或浪费用户流量。比如一屏的图片很多,如果全部加载完,用户不一定能看得到,一次性耗费流量大而且首次等待时间较长。
这时候我们就可以用懒加载~~~
懒加载
懒加载,就是延迟加载的意思。
常见的一个场景就是,图片开始进入屏幕范围才加载。实现的原理是,预先给一个默认图片,当图片进入窗口可视范围时,再将src属性替换。
那什么时候图片开始进入屏幕呢?我们可以通过这三者来计算:
- 窗口顶部与文档顶部之间的距离(scrollTop)
- 可视窗口的高度(clientheight)
- 图片与文档顶部的距离(offsetTop)
计算屏幕可视窗口大小
- window.innerHeight 标准浏览器及IE9+
- document.documentElement.clientHeight 标准浏览器及低版本IE标准模式
- document.body.clientHeight 低版本混杂模式
|
|
计算顶部与文档顶部之间的距离
- window.pageYOffset 标准浏览器及IE9+
- document.documentElement.scrollTop 兼容ie低版本的标准模式
- document.body.scrollTop 兼容混杂模式
|
|
计算图片与文档顶部的距离
可以通过offsetTop来计算
MDN上对于offsetTop的定义:返回当前元素相对于其 offsetParent 元素的顶部的距离。
HTMLElement.offsetParent 是一个只读属性,返回一个指向最近的(closest,指包含层级上的最近)包含该元素的定位元素。如果没有定位的元素,则 offsetParent 为最近的 table cell 元素对象或根元素(标准模式下为 html;quirks 模式下为 body)。当元素的 style.display 设置为 “none” 时,offsetParent 返回 null。offsetParent 很有用,因为 offsetTop 和 offsetLeft 都是相对于其内边距边界的。
所以图片与文档顶部的距离可以这样计算:
|
|
懒加载的实现:
当 bodyScrollTop + bodyHeight >= imageTop时加载图片
|
|
当图片滚动到刚进入视图时,才会加载。但是可能由于网络速度较慢等原因,图片滚动到可视区域内时都没有加载完毕,会出现闪屏。
为了更好的用户体验,我们可以在用户再滚动半屏就能看到图片的位置就加载图片,加载的条件判断可以改成:
|
|
另外,在加载图片完成后会触发onload事件,但img加载完成就会解除onload事件,src是异步加载图片的,如果在绑定事件前就已经加载完成,onload事件不会触发,这时可以先用img.complete属性判断。
complete 属性可返回浏览器是否已完成对图像的加载,如果加载完成,则返回 true,否则返回fasle。
在图片加载完成后,就可以在handleLoadSuccess方法中获取图片宽高,设置图片的显示方式了。
注意: 懒加载图片应该先预加载默认图片(俗称:占位图),用于计算图片位置。