专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

前端性能:首屏优化体验之方法——懒加载即lazy-load

ins518 2024-10-07 13:27:01 技术文章 11 ℃ 0 评论

链接:https://juejin.im/book/5b936540f265da0a9624b04b/section/5bb6218ee51d450e7762f873

Lazy-Load,翻译过来是“懒加载”。它是针对图片加载时机的优化:在一些图片量比较大的网站(比如电商网站首页,或者团购网站、小游戏首页等),如果我们尝试在用户打开页面的时候,就把所有的图片资源加载完毕,那么很可能会造成白屏、卡顿等现象,因为图片真的太多了,一口气处理这么多任务,浏览器做不到啊!

但我们再想,用户真的需要这么多图片吗?不对,用户点开页面的瞬间,呈现给他的只有屏幕的一部分(我们称之为首屏)。只要我们可以在页面打开的时候把首屏的图片资源加载出来,用户就会认为页面是没问题的。至于下面的图片,我们完全可以等用户下拉的瞬间再即时去请求、即时呈现给他。这样一来,性能的压力小了,用户的体验却没有变差——这个延迟加载的过程,就是 Lazy-Load。

现在我们打开掘金首页:

右侧可能会出现的图片,即下图示例:

大家现在以尽可能快的速度,疯狂向下拉动页面。发现什么?是不是发现我们图示的这个图片的位置,会出现闪动——有时候我们明明已经拉到目标位置了,文字也呈现完毕了,图片却慢半拍才显示出来。这是因为,掘金首页也采用了懒加载策略。当我们的页面并未滚动至包含图片的 div 元素所在的位置时,它的样式是这样的:

我们把代码提出来看一下:

<div data-v-b2db8566="" 
 data-v-009ea7bb="" 
 data-v-6b46a625="" 
 data-src="https://user-gold-cdn.xitu.io/2018/9/27/16619f449ee24252?imageView2/1/w/120/h/120/q/85/format/webp/interlace/1" 
 class="lazy thumb thumb" 
 style="background-image: none; background-size: cover;"> 
</div>

我们注意到 style 内联样式中,背景图片设置为了 none。也就是说这个 div 是没有内容的,它只起到一个占位的作用。

这个“占位”的概念,在这个例子里或许体现得不够直观。最直观的应该是淘宝首页的 HTML Preview 效果:

我们看到,这个还没来得及被图片填充完全的网页,是用大大小小的空 div 元素来占位的。

一旦我们通过滚动使得这个 div 出现在了可见范围内,那么 div 元素的内容就会发生变化,呈现如下的内容:

我们给 style 一个特写:

style="background-image: url("https://user-gold-cdn.xitu.io/2018/9/27/16619f449ee24252?imageView2/1/w/120/h/120/q/85/format/webp/interlace/1"); background-size: cover;"

可以看出,style 内联样式中的背景图片属性从 none 变成了一个在线图片的 URL。也就是说,出现在可视区域的瞬间,div 元素的内容被即时地修改掉了——它被写入了有效的图片 URL,于是图片才得以呈现。这就是懒加载的实现思路。

写一个 Lazy-Load

基于上面的实现思路,我们完全可以手动实现一个属于自己的 Lazy-Load。

Lazy-Load 的思路及实现方式为大厂面试常考题,引起重视

首先新建一个空项目,目录结构如下:

大家可以往 images 文件夹里塞入各种各样自己喜欢的图片。

我们在 index.html 中,为这些图片预置 img 标签:

在懒加载的实现中,有两个关键的数值:一个是当前可视区域的高度,另一个是元素距离可视区域顶部的高度

当前可视区域的高度, 在和现代浏览器及 IE9 以上的浏览器中,可以用 window.innerHeight 属性获取。在低版本 IE 的标准模式中,可以用 document.documentElement.clientHeight 获取,这里我们兼容两种情况:

const viewHeight = window.innerHeight || document.documentElement.clientHeight

元素距离可视区域顶部的高度,我们这里选用 getBoundingClientRect() 方法来获取返回元素的大小及其相对于视口的位置。对此 MDN 给出了非常清晰的解释:

该方法的返回值是一个 DOMRect 对象,这个对象是由该元素的 getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的 CSS 边框集合 。

DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right 和 bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。

其中需要引起我们注意的就是 left、top、right 和 bottom,它们对应到元素上是这样的:


色背景为视口:viewHeight,即clientHeight。色元素为单一张图片位置,由getBoundingClientRect() 方法获取。

可以看出,top 属性代表了元素距离可视区域顶部的高度,正好可以为我们所用:

根据distance就可以判断,滚动scroll页面时,图片是否出现在可视区域内。

当然还有个问题,页面窗口在进行缩放resize,或者滚动scroll时,是一个频繁触发的事件,因此需要进行防抖和节流处理的,在这里

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表