从懒加载到回流

突然有个疑问,懒加载?比如作用于图片,就是监听滚动事件,当滚动条拉下到一定距离图片才加载出来,可以为用户省流量,减少服务器压力(此处可能说错。)

而问题来了,图片怎么感觉是网页一开始加载就随着加载的呢,那怎么叫他停?想到这我看了篇关于浏览器渲染原理的文章,翻译写的非常好!可以先看看再回来(最下面)。

这里提到了reflow,应该就是我们所说的回流了。回流会加大浏览器的负担,在上面那篇文章里有所提到,解决办法就是1、尽量把元素放在内存处理;2、用类名操作(一次性操作多个嘛,按我的理解,毕竟reflow一般会异步执行或者累积执行);3、对绝对定位的元素来进行操作;4、尽量操作低层次的节点(下是低);

说完回流,说说懒加载。懒加载图片先用个统一的普通图片代替,真正的图片用比如data-src=“xxx.jpg”写在img标签里,等滚到图片附近时再把真正的引用替换给src。这里我想到原生js单是要得到浏览器可视窗口大小,为了兼容就有3个api要写!天哪,写完发现jQuery真亲切,帮你封装好了(window.innerHeight || document.documentElement.ClientHeight || document.body.ClientHeight,而jq就一个$(window).height())。

滚动监听需要注意性能优化,这里来个节流函数,话不多说,抄了端代码过来:

// 简单的节流函数
//fun 要执行的函数
//delay 延迟
//time  在time时间内必须执行一次
function throttle(fun, delay, time) {
    var timeout,
        startTime = new Date();
    return function() {
        var context = this,
            args = arguments,
            curTime = new Date();
        clearTimeout(timeout);
        // 如果达到了规定的触发时间间隔,触发 handler
        if (curTime - startTime >= time) {
            fun.apply(context, args);
            startTime = curTime;
            // 没达到触发间隔,重新设定定时器
        } else {
            timeout = setTimeout(fun, delay);
        }
    };
};
// 实际想绑定在 scroll 事件上的 handler
function lazyload(event) {}
// 采用了节流函数
window.addEventListener('scroll',throttle(lazyload,500,1000));

这throttle函数有个值得说下的地方,就是为什么要返回一个函数呢?想弄明白你就要知道如果不这样做,直接把函数里的变量写到throttle会怎样?本来不想告诉你们,自己去试一试的。算了,我这人忍不住要说,嗯。。。算了,说一半吧,在于arguments的不同。当然,还有一个作用...不然每次滚动startTime都刷新还玩个X。补充一句window.addEventListener('scroll',throttle(lazyload,500,1000));throttle(lazyload,500,1000)已经变成他返回的函数啦。。。

完。

参考:

http://coolshell.cn/articles/9666.html 《浏览器的渲染原理简介》

http://www.cnblogs.com/flyromance/p/5042187.html《滚动加载图片(懒加载)实现原理》

https://zhuanlan.zhihu.com/p/24057749 《前端如何实现图片懒加载(lazyload) 提高用户体验》

发表评论

电子邮件地址不会被公开。 必填项已用*标注