懒加载和预加载的区别_【web】懒加载 so easy!

58f05e74f5993fd501775f05ad7ba21a.png

文章目录

    • 一、前言

    • 二、关联知识点

      • 1、HTML5的`data-*`

      • 2、防抖和节流

    • 二、`getBoundingClientRect()`实现懒加载

      • 1、API介绍

      • 2、懒加载实现

    • 三、`IntersectionObserver`实现懒加载

      • 1、API

      • 2、懒加载实现

    • 四、css属性loading实现懒加载

      • 1、API

      • 2、懒加载实现

    • 五、总结

一、前言

什么是懒加载?

懒加载顾名思义,相对于正常资源的加载显得不那么勤快;只会在页面中需要用的时候才去加载相应资源,这样的好处是能够减少页面加载时的不必要的请求,减轻浏览器请求负担,给予用户更好的体验!

  在前端开发中,懒加载十分有必要,很多第三方的组件库/js库都具备了懒加载的特性。最常见的就是图片的懒加载,本文就围绕图片的懒加载实现展开,介绍三种图片懒加载的实现方式:

  • 1、基于getBoundingClientRect()的懒加载方式;

  • 2、基于IntersectionObserver的懒加载方式;

  • 3、基于css属性loading的懒加载方式;

  其原理为:

  • 1、判断元素是否在浏览器视口中;

  • 2、监听浏览器滚动事件(scroll);

  • 3、当元素滚动出现在视口中时,进行资源加载`

二、关联知识点

1、HTML5的data-*

  开发者喜欢在HTML标签上添加自定义属性来存储和操作数据。但这样做的问题是,你不知道将来会不会有其它脚本把你的自定义属性给重置掉,此外,你这样做也会导致html语法上不符合Html规范,以及一些其它副作用。于是HTML5规范里增加了一个自定义data属性,你可以拿它做很多有用的事情。

定义和用法:

  • data-*属性用于存储私有页面后应用的自定义数据

  • data-*属性可以在所有的 HTML 元素中嵌入数据。

  • element.getAttribute("data-*")可以获取html标签中定义的数据;

  • element.dataset.*可以获取html标签中定义的数据;

2、防抖和节流

(后续补充完整内容)

二、getBoundingClientRect()实现懒加载

  当在使用一个不常使用/看到的API时,保持先查看Can I Use,再决定是否使用的好习惯;从图中可以看到几乎所有的浏览器的版本都是支持getBoundingClientRect的,那么就可以不用考虑兼容性问题放心使用了:222a90979f6a95f3871e31159d3c5de1.png

1、API介绍

Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。
返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合,就是该元素的 CSS 边框大小。返回的结果是包含完整元素的最小矩形,并且拥有left, top, right, bottom, x, y, width, 和 height这几个以像素为单位的只读属性用于描述整个边框。除了width 和 height 以外的属性是相对于视图窗口的左上角来计算的。1bf6fe7a2b2a673df446325fc468b506.png

2、懒加载实现

实现步骤:

  • 1)通过ele.getBoundingClientRect().top获取元素到视口高度;

  • 2)通过document.documentElement.clientHeight获取视口的高度;

  • 3)判断元素是否在视口中,如果出现在视口中对资源进行加载;

  • 4)监听浏览器滚动scroll事件,并且在监听中重复步骤1-3;
    代码如下:

<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>懒加载title><style>.imglazy {margin-top: 800px;}style><script>// 方式一:使用getBoundingClientRect获取元素与视口的高度,判断元素是否在视口内,在监听滑动事件对元素属性进行修改;let laodingImg = () => {let ele = document.getElementById("lala");let ch = document.documentElement.clientHeight;let eh = ele.getBoundingClientRect().top;
console.log(eh);if (ch > eh) {//使用元素的dataset获取自定义的私有数据,也就是图片真正的地址,并将其赋值给img的src属性进行资源请求
ele.src = ele.dataset.src;}};
window.onload = () => {laodingImg();};//建议进行节流处理(此处为了方便就不做处理)
window.onscroll = () => {laodingImg();};script>head><body>
/*使用src存放私有的自定义数据,真正的图片请求地址*/<imgid="lala"class="imglazy"src="https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg"alt="123"/>body>html>

执行结果如下图:当没有滚动鼠标时,图片不在视口内,Network中并没有对图片进行请求,当滚动鼠标直至img元素出现在视口中,进行图片资源请求,显示图片。e81826e26081868e5ca56329c5a0055a.gif

三、IntersectionObserver实现懒加载

  查看Can I UseIntersectionObserver的兼容性:5a4d238aa2dbaae1c15367b7d4625ff9.png

1、API

IntersectionObserver接口 (从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。
当一个IntersectionObserver对象被创建时,其被配置为监听根中一段给定比例的可见区域。一旦IntersectionObserver被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配置监听多个目标元素。
使用方法:

var io = new IntersectionObserver(callback, option);
// 开始观察
io.observe(document.getElementById(‘example’));
// 停止观察
io.unobserve(element);
// 关闭观察器
io.disconnect();

callback函数的参数(entries)是一个数组,每个成员都是一个IntersectionObserverEntry对象

可以简单的理解为:IntersectionObserver是一个能够监听元素是否到了当前视口的事件!
IntersectionObserverEntry提供观察元素的信息,有七个属性。intersectionRatio和isIntersecting是用来判断元素是否可见的

  • boundingClientRect 目标元素的矩形信息

  • intersectionRatio 相交区域和目标元素的比例值 intersectionRect/boundingClientRect 不可见时小于等于0

  • intersectionRect 目标元素和视窗(根)相交的矩形信息 可以称为相交区域

  • isIntersecting 目标元素当前是否可见 Boolean值 可见为true

  • rootBounds 根元素的矩形信息,没有指定根元素就是当前视窗的矩形信息

  • target 观察的目标元素

  • time 返回一个记录从IntersectionObserver的时间到交叉被触发的时间的时间戳

2、懒加载实现

直接上代码:

<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>懒加载title><style>.imglazy {margin-top: 800px;}style><script>//方式二
window.onload = ()=>{let ele = document.getElementById("lala");//使用IntersectionObserver创建实例let observer = new IntersectionObserver(changes =>{//遍历包含的IntersectionObserverEntry
changes.forEach(change => {
console.log(change.isIntersecting);//判断是否出现在视口if(change.isIntersecting){let img = change.target;
img.src = img.dataset.src;//加载完卸载observer实例
observer.unobserve(img)}});})//调用实例
observer.observe(ele)}script>head><body><imgid="lala"class="imglazy"src="https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg"alt="123"/>body>html>

结果如下:b2ada4ac7eb97ca1e219b189c8eb698a.gif

四、css属性loading实现懒加载

Can I Use:css的loading属性兼容性并不好,总体只有72%;并且chrome中也是最近的版本才采用了!(不推荐使用,但是还是要介绍下)68989fb51c8c5cf76fbd069b0a0ffe2a.png

1、API

HTML元素延迟加载属性 —— loading属性值lazy允许浏览器选择性加载IMG元素,根据用户滚动操作至其元素附近执行加载,一定程度起到节流的作用;

2、懒加载实现
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>懒加载title><style>.imglazy {margin-top: 800px;}style>head><body><imgclass="imglazy"loading="lazy"src="https://res.wx.qq.com/wxdoc/dist/assets/img/0.4cb08bb4.jpg"alt="123"/>body>html>

但是呢,我在chrome中使用loading="lazy"并没有实现懒加载,电脑上的chrome版本为87,这也再次印证就目前来看,loading="lazy"的兼容性实在不好:e43e54b6cfb380da71f60275094d27b4.gif

五、总结

  综合上述,可以看到:

  • getBoundingClientRect懒加载方式代码量最大(其实也不是很多),但是兼容性和使用率是最高的(推荐);

  • IntersectionObserver懒加载方式相对而言是体验最好的,其结合监听和节流一体,体验最好,代码量不多,兼容性也好(十分推荐);

  • css的laoding懒加载方式,虽然代码最简单,只需要添加一个属性就可以,但是兼容性太差,就目前来看不适合使用

欢迎大家关注本人的微信公众号,微信公众号将不定期发送相应学习文章和教程

微信号:chiyizao

88ea60b79a873042a9477cc93fee3357.png

或者微信公众号搜索:
迟亦早
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值