美文网首页JAVA
首屏加载速度优化——图片懒加载

首屏加载速度优化——图片懒加载

作者: 我向你奔 | 来源:发表于2018-05-02 18:01 被阅读58次
    什么是懒加载

    懒加载其实就是延迟加载,是一种对网页性能优化的方式,比如当访问一个页面的时候,优先显示可视区域的图片而不一次性加载所有图片,当需要显示的时候再发送图片请求,避免打开网页时加载过多资源。

    原理

    <img>标签有一个属性是src,用来表示图像的URL,当这个属性的值不为空时,浏览器就会根据这个值发送请求。如果没有src属性,就不会发送请求。我们先不给<img>设置src,把图片真正的URL放在另一个属性data-src中,在需要的时候也就是图片进入可视区域的之前,将URL取出放到src中。

    实现

    html结构

    <div class="container">
      <div class="img-area">
        <img class="my-photo" alt="loading" data-src="./img/img1.png">
      </div>
      <div class="img-area">
        <img class="my-photo" alt="loading" data-src="./img/img2.png">
      </div>
      <div class="img-area">
        <img class="my-photo" alt="loading" data-src="./img/img3.png">
      </div>
      <div class="img-area">
        <img class="my-photo" alt="loading" data-src="./img/img4.png">
      </div>
      <div class="img-area">
        <img class="my-photo" alt="loading" data-src="./img/img5.png">
      </div>
    </div>
    

    仔细观察一下,<img>标签此时是没有src属性的,只有alt和data-src属性。
    alt属性是一个必需的属性,它规定在图像无法显示时的替代文本。
    data-* 全局属性:构成一类名称为自定义数据属性的属性,可以通过HTMLElement.dataset来访问。

    如何判断元素是否在可视区域

    方法一

    ① 通过document.documentElement.clientHeight获取屏幕可视窗口高度
    ② 通过element.offsetTop获取元素相对于文档顶部的距离
    ③ 通过document.documentElement.scrollTop获取浏览器窗口顶部与文档顶部之间的距离,也就是滚动条滚动的距离

    然后判断③-②<①是否成立,如果成立,元素就在可视区域内。

    方法二

    通过getBoundingClientRect()方法来获取元素的大小以及位置:这个方法返回一个名为ClientRect的DOMRect对象,包含了top、right、botton、left、width、height这些值。

    假设const bound = el.getBoundingClientRect();来表示图片到可视区域顶部距离;
    并设 const clientHeight = window.innerHeight;来表示可视区域的高度。

    随着滚动条的向下滚动,bound.top会越来越小,也就是图片到可视区域顶部的距离越来越小,当bound.top===clientHeight时,图片的上沿应该是位于可视区域下沿的位置的临界点,再滚动一点点,图片就会进入可视区域。也就是说,在bound.top<=clientHeight时,图片是在可视区域内的。

    function isInSight(el) {
      const bound = el.getBoundingClientRect();
      const clientHeight = window.innerHeight;
      //如果只考虑向下滚动加载
      //const clientWidth = window.innerWeight;
      return bound.top <= clientHeight + 100;   // +100是为了提前加载。
    }
    

    页面打开时需要对所有图片进行检查,是否在可视区域内,如果是就加载。

    function checkImgs() {
      const imgs = document.querySelectorAll('.my-photo');
      Array.from(imgs).forEach(el => {
        if (isInSight(el)) {
          loadImg(el);
        }
      })
    }
    
    function loadImg(el) {
      if (!el.src) {
        const source = el.dataset.src;
        el.src = source;
      }
    }
    

    JQ实现懒加载

    有一款jquery的lazyload插件可以实现图片延迟加载的插件。依赖JQuery引入lazyload.js,对我们想要延迟加载的图片添加lazy样式,用"data-original"替换图片的引用路径。

    <!-- 对img标签使用 -->
    <img class="lazy" data-original="img/example.jpg">
    <!-- 延迟加载元素的背景图 -->
    <div class="lazy" data-original="img/bg.jpg">
        ...
    </div>
    

    在JS文件中调用lazyload()方法

    $().ready(function(){
        //可任意选择你想延迟加载的目标元素,例如直接使用样式名lazy作为选择条件
        $("img .lazy").lazyload({
             placeholder : "img/grey.gif", //占位图
             effect: "fadeIn", // 加载效果
             threshold: 200, // 提前加载
             event: 'click',  // trigger
             container: $("#container"),  //指定容器
             failurelimit : 5 // 发生混乱时的hack手段
        })
    })
    

    placeholder:占位图片,图片路径值,图片加载时占位图自动隐藏;
    effect:图片载入时动画效果,值有show(直接显示),fadeIn(淡入),slideDown(滑入)等jq常用效果;
    threshold:提前开始加载高度;数字值,是离需要加载目标的高度。如设置为200,表示滚动条在离目标位置还有200的高度时就开始加载图片,避免用户看到图片加载过程;
    event:图片加载trigger;值有click(点击),mouseover(鼠标划过),sporty(运动的),foobar(…);
    container:指定容器;lazyload默认在滚动浏览器滚动条时生效,这个参数可以让你在滚动某DIV的滚动条时执行懒加载;
    failurelimit:提高稳定性,若是某一张该被加载的图片未能正确加载,则加载其后的第N张图;

    相关文章

      网友评论

        本文标题:首屏加载速度优化——图片懒加载

        本文链接:https://www.haomeiwen.com/subject/rwecrftx.html