0%

懒加载

开头

作为最常见的优化页面的一种手段,记录一下学习笔记

正文

什么是懒加载

  • 也叫延迟加载,即让页面依赖的一些非关键资源,先不加载,在后期达到某些触发条件时,在加载
  • 这里的关键资源指决定和影响当前访问页面的一些资源;非关键资源,比如针对页面某一部分的一些脚本、动态切换的样式等

目的

减少资源加载带来的响应时间过长,造成用户体验不好

具体表现

  • 在页面滚动到某一部分,加载当前位置需要显示的图片和相关资源
  • 面板切换,要切换时,在加载将要显示的资源
  • 等等

实现

  • 对上述第一种情况进行一个简单的效果实现
  • 页面有3部分,每一部分都占满整个屏幕,显示一张图片

思路

  • 对一部分的图片不作处理
  • 对剩下的2部分的图片的src不先不设置,把资源路径添加到data-src里
  • 对整个文档添加一个滚动事件
  • 每次滚动事件的函数触发时,获取当前文档滚动的height
  • 当滚动的位置达到我们指定的值后,通过js给图片的src添加资源路径

用到的api

  • data-***:不具有表现意义的一个属性,用于给dom添加自定的片段数据
  • 滚动事件:mousewheel
  • 获取文档滚动的高度:scrollTop

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!-- CSS -->
<style>
body {
margin: 0;
overflow-x: hidden;
}

.box>div {
width: 100vw;
height: 100vh;
margin: 0 auto;
}

img {
width: 100%;
height: 100%;
}

.two,
.three {
visibility: hidden;
opacity: 0;
transition: all 0.5s;
}
</style>
<!-- HTML -->
<div class="box" id="box">
<div class="one">
<img src="./img/a.jpg" alt="">
</div>
<div class="two">
<img src="" data-src="./img/b.jpg" alt="">
</div>
<div class="three">
<img src="" data-src="./img/c.jpg" alt="">
</div>
</div>
<script>
let box = document.querySelector('#box')
box.addEventListener('mousewheel', () => {
if (document.documentElement.scrollTop > 10) {
document.querySelector('.two').style.visibility = 'visible'
document.querySelector('.two').style.opacity = '1'
document.querySelector('.two img').src = document.querySelector('.two img').getAttribute(
'data-src')
}
if (document.documentElement.scrollTop > 722) {
document.querySelector('.three').style.visibility = 'visible'
document.querySelector('.three').style.opacity = '1'
document.querySelector('.three img').src = document.querySelector('.three img').getAttribute(
'data-src')
}
})
</script>
  • 打开chrome调试工具,查看network,发现页面一开始只加载了a图片
  • 当滚动到指定位置后,才开始加载需要后面的资源

关于获取dom的大小、位置

提到了scrollTop,顺带总结一下这几个api的区别

clientHeight、clientWidth

  • 获取dom的height(width)+padding(如果没设置,为0)
  • 这里还有一个同样功能的api:getClientRects
  • 两者的区别:前者对小数取整;后者保留

clientTop、clientLeft

  • 获取dom的border-top(left)

scrollHeight、scrollWidth

  • 获取dom的整个内容长度(比如div的height是100px,并设置了overflow-y:scroll后,div内部内容的height长度)
  • 后者同理

scrollTop、scrollLeft

  • 获取dom滑动出可视区域的部分的height(width)

offsetheight、offsetWidth

  • 获取dom的height(width)+padding+border

offsetTop、offsetLeft

  • 获取目标dom离最近的已定位元素的margintop(left)
  • 这里还有个api,offsetParent用来获取离目标元素最近的已定位的元素