Without jQuery:lazyload.js
Without jQuery 系列之:lazyload.js
什么是延时加载?
图片延迟加载也称 “懒加载”,通常应用于图片比较多的网页
为什么要使用延时加载?
假如一个网页中,含有大量的图片,当用户访问网页时,那么浏览器会发送n个图片的请求,加载速度会变得缓慢,性能也会下降。如果使用了延时加载,当用户访问页面的时候,只加载首屏中的图片;后续的图片只有在用户滚动时,即将要呈现给用户浏览时再按需加载,这样可以提高页面的加载速度,也提升了用户体验。而且,统一时间内更少的请求也减轻了服务器中的负担。
延时加载的原理
基本原理就是最开始时,所有图片都先放一张占位图片(如灰色背景图),真实的图片地址则放在 data-src
中,这么一来,网页在打开时只会加载一张图片。
然后,再给 window
或 body
或者是图片主体内容绑定一个滚动监听事件,当图片出现在可视区域内,即滚动距离 + 窗体可视距离 > 图片到容器顶部的距离
时,将讲真实图片地址赋值给图片的 src,否则不加载。
使用原生js实现图片的延时加载
延时加载需要传入的参数:
|
|
其中:
wrapper
:延时加载的容器。在该容器下,所有符合图片选择器条件的图片均会延时加载。selector
:图片选择器。表示需要延迟加载的图片的选择器,如img.lazyload-image
,默认为所有的 img 标签。imgSrc
:图片真实地址存放属性。表示图片的真实路径存放在标签的哪个属性中,默认为data-src
。defaultSrc
:初始加载的图片地址,默认为空,当为空时,不处理延时加载的图片的路径,若图片本身没有路径,则显示为空。
获取容器中所有的图片。
|
|
该函数在容器中查找出所有需要延时加载的图片,并将 NodeList 类型的对象转换为允许使用 map 函数的数组。
如果设置了初始图片地址,则加载。
|
|
给 window 绑定滚动事件
每次滚动网页时,都会遍历所有的图片,将图片的位置与当前滚动位置作对比,当符合加载条件时,将图片的真实地址赋值给图片,并将图片从集合中移除;当所有需要延时加载的图片都加载完毕后,将滚动事件取消绑定。
测试是否可行
测试结果:
从chrome的网络请求图中可见,5张图片并不是在网页打开的时候就请求了,而是当滑动到某个区域时才触发加载,基本实现了图片的延时加载。
测试结果
性能调整
上述只是简单的实现了一个延时加载的 demo,还有很多地方需要调整和完善。
调整 1:onscroll 函数可能会被覆盖
问题:
因为有时候页面需要滚动无限加载时,插件会重写 window 的 onscroll 函数,从而导致图片的延时加载滚动监听失效。
解决办法:
需要更改为将监听事件注册到 window 上,移除时只需要移除相应的事件即可。
调整后的代码
|
|
调整2:滚动时的回调函数执行次数太多
问题
在本次测试中,从动图最后可以看到,当滚动网页时,loadImage 函数执行了非常多次,滚轮每向下滚动 100px 基本上就要执行 10 次左右的 loadImage,若处理函数稍微复杂,响应速度跟不上触发频率,则会造成浏览器的卡顿甚至假死,影响用户体验。
解决办法
使用 throttle
控制触发频率,让浏览器有更多的时间间隔去执行相应操作,减少页面抖动。
调整后的代码:
调整后的测试
从动图可见,在滚动的时候,调用判断的回调的次数少了很多。而且也不影响图片的延时加载。
调整后的测试结果
封装为插件形式
上述代码拷贝到项目中即可使用,使用方式:
|
|
若在 IE8 中使用,没有 map 函数时,请在引用插件前加入下列处理 map 函数兼容性的代码:
Enjoy!!!