"懒"出高效:利用懒加载技术优化网页速度

前言

本文将探讨懒加载技术如何能有效优化网页加载性能,带来更顺畅的浏览体验。

并且深入了解懒加载的原理,同时给出具体的实现方法。

接下来就让我们一起探索这项革命性的前端技术,掌握提升网页速度的秘密!

实现

html讲解

首先我们准备了一张图片

html 复制代码
    <img src = 'https://img.36krcdn.com/20190905/v2_1567641974410_img_000' />

当这段代码在浏览器时会发生什么?

答案是会立即发起一个对 'https://img.36krcdn.com/20190905/v2_1567641974410_img_000' 这个图片资源的请求,并尝试立即下载和渲染这个图片。

那如果有10张、20张、甚至更多呢?如果都同时去加载,这必然会给浏览器带来巨大的负担!

所以我们不应该一次将所有的图片全部加载,而是当图片到了用户屏幕里面才去加载,这便是懒加载

接下来我来为大家讲解如何去实现懒加载

首先准备11张图片,并将图片的src让他去加载https://misc.360buyimg.com/mtd/pc/common/img/blank.png,该链接是一个只有一像素的图片,然后为img添加data-src数据属性,在data-src数据属性里面才是真正要去加载的图片,具体代码如下

html 复制代码
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000" />
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641293753_img_png">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642423719_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190808/v2_1565254363234_img_jpg">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425030_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425101_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425061_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190904/v2_1567591358070_img_jpg">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567640518658_img_png">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974454_img_000">

js讲解

懒加载简单来说就是图片到了可视区域才去加载,那么如何去做判断呢?

  • 首先第一步我们肯定是需要拿到所有图片的dom元素的,并判断有多少张图片
js 复制代码
    const imgList = document.getElementsByTagName('img');
    const num = imgList.length;
  • 第二步编写懒加载的函数
js 复制代码
function lazyload() {
            // 获取可视区域一屏的高度
            let screenHeight = document.documentElement.clientHeight;
            console.log(screenHeight);
            // 获取滚动条滚动的距离 多浏览器适配
            let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            console.log(scrollTop);
            for (let i = n; i < num; i++) {
                
                if(imgList[i].offsetTop < screenHeight + scrollTop) {
                    imgList[i].src = imgList[i].getAttribute('data-src');
                    // 记录已经加载过的图片的下标
                    n = i + 1;
                    if(n === num) {
                        // console.log('所有图片加载完成');
                        window.removeEventListener('scroll', throttleLazyload)
                    }
                }
        }
  1. 它首先获取当前浏览器窗口的可视区域高度 screenHeight,以及当前滚动条滚动的距离 scrollTop

  2. 然后遍历 imgList 数组中的图片元素。对于每个图片元素:

    • 检查该图片元素的 offsetTop 是否小于 screenHeight + scrollTop,也就是检查图片是否已经进入可视区域。
    • 如果已经进入可视区域,则将图片的 src 属性设置为 data-src 属性中存储的图片 URL,从而加载图片。
    • 同时记录下已经加载过的图片的下标 n
    • 如果所有图片都已经加载完成 (n === num),则移除窗口的 scroll 事件监听器,因为不再需要继续执行懒加载逻辑。
  • 此时只需要监听鼠标滚轮事件触发懒加载函数即可
js 复制代码
window.addEventListener('scroll', lazyload)

这个时候其实已经实现滚动鼠标即可加载图片了,但是当我们打开网页时,第一页已经在可视区域的图片并未加载,因为还没有滚动鼠标,所以我们需要提前调用一次图片加载

js 复制代码
    document.addEventListener('DOMContentLoaded', () => {
            console.log('DOMContentLoaded');
            lazyload()
        })

DOMContentLoaded 事件在 HTML 文档完全加载并解析完成后触发,此时 DOM 树已经完全构建好,但是图像、样式表和脚本可能尚未完成加载。

通过将 lazyload() 的调用放在 DOMContentLoaded 事件的回调函数中,可以确保在 DOM 结构完全构建好之后再执行懒加载逻辑。这样可以避免在 DOM 还没有完全加载的情况下就开始执行懒加载,从而导致可能出现的错误,体现了对生命周期的理解

这时候我们就已经实现了懒加载的功能,但是滚动事件频繁触发,我们并不需要如此的频繁,可以采取一个节流的措施,让我们来实现一个简单得节流函数吧

js 复制代码
    function throttle(func, limit) {  
        let inThrottle;  
         return function() {  
            const context = this;  
         const args = arguments;  
         if (!inThrottle) {  
           func.apply(context, args);  
              inThrottle = true;  
              setTimeout(() => inThrottle = false, limit);  
         }  
          };  
    } 
  1. throttle 函数接受两个参数:

    • func: 需要节流执行的函数。
    • limit: 限制函数执行的时间间隔(单位为毫秒)。
  2. throttle 函数返回一个新的函数,这个新函数就是经过节流处理的版本。

  3. 在新函数的内部:

    • 定义一个 inThrottle 变量,用于记录函数是否正在执行。
    • 当函数被调用时,先检查 inThrottle 变量是否为 true
    • 如果 inThrottlefalse,则执行原始函数 func,并将 inThrottle 设置为 true
    • 然后使用 setTimeout 设置一个定时器,在 limit 毫秒后将 inThrottle 重置为 false

最后修改scroll事件

js 复制代码
        const throttleLazyload = throttle(lazyload, 200)
        window.addEventListener('scroll', throttleLazyload)

最终我们实现了页面的懒加载效果

总结

本文带大家深入学习了结合节流去实现页面的懒加载效果,通过结合节流优化性能,并注意一些细节实现,可以开发出一个优秀的懒加载功能,大幅提升网页的加载性能和用户体验。相信大家在认真学习了本文之后也能自己去做一个懒加载效果了,让我们一起动手coding起来吧!

完整代码

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>懒加载</title>
    <style>
        body{
            background-color: #000000;
        }
        img {
            display: block;
            margin-bottom: 50px;
            width: 400px;
            height: 400px;
        }
    </style>
</head>
<body>
    <!-- data-src为数据属性 -->
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000" />
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641293753_img_png">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642423719_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190808/v2_1565254363234_img_jpg">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425030_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425101_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567642425061_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190904/v2_1567591358070_img_jpg">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567640518658_img_png">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974410_img_000">
    <img src = 'https://misc.360buyimg.com/mtd/pc/common/img/blank.png' data-src="https://img.36krcdn.com/20190905/v2_1567641974454_img_000">
    </script>
    <script>
        const imgList = document.getElementsByTagName('img');
        const num = imgList.length;
        // console.log(imgList);
        let n = 0;
        // 注册在scroll事件中的触发函数
        const throttleLazyload = throttle(lazyload, 200)
        window.addEventListener('scroll', throttleLazyload)
        // DOMContentLoaded html和css页面加载完成时触发,保证第一次页面的图片不用滚轮加载图片
        document.addEventListener('DOMContentLoaded', () => {
            console.log('DOMContentLoaded');
            lazyload()
        })
        function lazyload() {
            // 获取可视区域一屏的高度
            let screenHeight = document.documentElement.clientHeight;
            console.log(screenHeight);
            // 获取滚动条滚动的距离 多浏览器适配
            let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            console.log(scrollTop);
            for (let i = n; i < num; i++) {
                
                if(imgList[i].offsetTop < screenHeight + scrollTop) {
                    imgList[i].src = imgList[i].getAttribute('data-src');
                    // 记录已经加载过的图片的下标
                    n = i + 1;
                    if(n === num) {
                        // console.log('所有图片加载完成');
                        window.removeEventListener('scroll', throttleLazyload)
                    }
                }
        }
    }
     
    function throttle(func, limit) {  
          let inThrottle;  
          return function() {  
            const context = this;  
            const args = arguments;  
            if (!inThrottle) {  
              func.apply(context, args);  
                 inThrottle = true;  
                 setTimeout(() => inThrottle = false, limit);  
            }  
        }
     }  
    </script>
</body>
</html>
相关推荐
SomeB1oody8 分钟前
【Rust自学】6.3. 控制流运算符-match
开发语言·前端·rust
m0_7482567834 分钟前
【Django自学】Django入门:如何使用django开发一个web项目(非常详细)
前端·django·sqlite
林小白的日常1 小时前
uniapp中wx.getFuzzyLocation报错如何解决
前端·javascript·uni-app
傻小胖1 小时前
React 脚手架配置代理完整指南
前端·react.js·前端框架
EterNity_TiMe_1 小时前
【论文复现】农作物病害分类(Web端实现)
前端·人工智能·python·机器学习·分类·数据挖掘
余生H2 小时前
深入理解HTML页面加载解析和渲染过程(一)
前端·html·渲染
吴敬悦2 小时前
领导:按规范提交代码conventionalcommit
前端·程序员·前端工程化
ganlanA2 小时前
uniapp+vue 前端防多次点击表单,防误触多次请求方法。
前端·vue.js·uni-app
卓大胖_2 小时前
Next.js 新手容易犯的错误 _ 性能优化与安全实践(6)
前端·javascript·安全
m0_748246352 小时前
Spring Web MVC:功能端点(Functional Endpoints)
前端·spring·mvc