图片懒加载从简单到复杂(1),【程序员必看】

本文介绍了图片懒加载的基本概念,如何通过CSS和JavaScript实现在页面加载时仅加载小尺寸的占位图片,以及滚动加载和使用Aspect-ratioboxes避免布局抖动的技术。同时讨论了如何选择合适的placeholder图片和Medium的懒加载策略。最后,提供了前端面试题文档的相关链接。
摘要由CSDN通过智能技术生成

这些优先级标记为high的图片会占用其他资源的下载带宽,可能会造成某些比较关键的资源(比如xhr call)加载缓慢,拖慢页面速度。

图片懒加载的简单实现

图片懒加载的思路一般时当页面加载时加载一个尺寸很小的占位图片(1kb以下),然后再通过js选择性的去加载真正的图片。

一个最简单的的实现如下:

// index.css

img[src] { filter: blur(0.2em); }

img { filter: blur(0em); transition: filter 0.5s; }

(function lazyLoad(){ const imageToLazy = document.querySelectorAll(‘img[src]’); const loadImage = function (image) { image.setAttribute(‘src’, image.getAttribute(‘src’)); image.addEventListener(‘load’, function() { image.removeAttribute(“src”); }) }

imageToLazy.forEach(function(image){ loadImage(image); })})()

通过懒加载之后,资源优先级如下。

图片懒加载的进阶实现–滚动加载

上面的方案并不完美,对于用户来说,不在视窗中的图片可能根本不是用户当前关心的图片,所以我们可以让这些图片出现在用户视窗中再进行加载。

运用Interp Observer 我们可以做到当图片滚动到视窗后再加载该图片。

(function lazyLoad(){ const imageToLazy = document.querySelectorAll(‘img[src]’); const loadImage = function (image) { image.setAttribute(‘src’, image.getAttribute(‘src’)); image.addEventListener(‘load’, function() { image.removeAttribute(“src”); }) }

const interpObserver = new InterpObserver(function(items, observer) { items.forEach(function(item) { if(item.isIntersecting) { loadImage(item.target); observer.unobserve(item.target); } }); });

imageToLazy.forEach(function(image){ interpObserver.observe(image); })})()

上面的这些demo都在https://github.com/hateonion/lazy-load 这个repo里面。

如何选择合适的Placeholder图片


在上面的demo中我们使用了placeholder图片,实际上,图片所占的位置是否确定对于我们选择placeholder图片有着很大的影响。

图片尺寸已知

图片尺寸已知出现的场景一般是博文的题图或者网站中一些固定尺寸的thumbnail,这些图的尺寸一般固定且一般不会发生改变。对于这种场景,我们可以加载对应尺寸的placeholder图片(如上一节的demo)。我们可以自己裁剪对应尺寸的的placeholder图片或者使用类似http://placeholder.com/ 这样的服务来获取placeholder图片。

图片尺寸未知

图片尺寸未知的情况下一般我们需要生成对应的thumbnail然后去加载我们生成的thumbnail去做placeholder。为了生成这些thumbnail你可以调用imagemagick或者调用一些在线的图片分割服务(比如七牛)

懒加载防止布局抖动


在图片懒加载时,由于图片的尺寸不定,浏览器难以计算需要给图片预留出的位置。所以当图片加载完成后会出现网页布局的抖动。

(image from From http://davidecalignano.it/lazy-loading-with-responsive-images-and-unknown-height/)

即使我们选择的placeholder很小,可以在毫秒级别完成下载,用户可能意识不到布局的抖动。但是在一些性能比较差的设备上,这种布局的抖动还是会一定程度上影响用户的体验。为了完全避免布局闪动,我们可以采用aspect ratio boxes 的技术来制作一个占位用的元素。

.lazy-load__container{ position: relative; display: block; height: 0;}

.lazy-load__container.feature { // feature image 的高宽比设置成42.8% // 对于其他图片 比如 post图片,高宽比可能会不同,可以使用其他css class去设置 padding-bottom: 42.8%;}

.lazy-load__container img { position: absolute; top:0; left:0; height: 100%; width: 100%;}

结果

上面这个实现的原理其实很简单,由于 padding-bottom (或者 padding-top)声明为百分比时是根据元素生成的box的 width 去计算百分比的,所以我们通过padding-bottom去声明一个对应高宽比的container。而这个container的具体尺寸会由尺寸确定的外层元素确定,但是高宽比始终保持一致。

而图片的尺寸设置成100%container的尺寸保证图片始终和container的尺寸保持一致。

需要注意的是上面这个方法并不能适配图片比例不一致的网站(比如本站),不过好在,为了用户体验,现在绝大多数网站的图片比例都有明确的要求,绝大多数情况下我们只适配保证网站常用的的几种图片宽高比例即可。

像Medium一样懒加载图片


Medium的懒加载图片的体验相信去 Medium 读过文章的同学都体验过了,可以说是非常的流畅。而其背后的技术其实也就是我们上面讲到的几种技术的组合。

  1. 使用 aspect ratio box 创建占位元素。

  2. 在html解析时只加载一个小尺寸的图片,并且添加blur效果。

  3. 最后使用js选择性的加载真实图片。

Demo 如下 codePen by José M. Pérez

总结


  1. 懒加载用户当前视窗中的图片可以提升页面的加载性能。

  2. 懒加载的思路是在html解析时先加载一个placeholder图片,最后再用js选择性的加载真实图片。

  3. 如果需要滚动加载可以使用 Interp Observer 。

  4. 对于固定尺寸和不定尺寸的图片,我们可以选择不同的服务去或者placeholder图片。
    自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!

//img2.imgtp.com/2024/03/13/H4lCoPEF.jpg" />

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里免费领取!

[外链图片转存中…(img-KxEvkwcE-1712322773961)]

[外链图片转存中…(img-mp1HnY7P-1712322773961)]

  • 10
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值