懒加载的3种实现方式
优势
- 性能收益:浏览器加载图片、decode、渲染都需要耗费资源,懒加载能节约性能消耗,缩短onload事件时间。
- 节约带宽:这个不需要解释。
通常,我们在html中展示图片,会有两种方式:
- img 标签
- css background-image
img的懒加载实现
img有两种方式实现懒加载:
- 事件监听(scroll、resize、orientationChange)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>event</title><style>img {background: #F1F1FA;width: 400px;height: 300px;display: block;margin: 10px auto;border: 0;}</style>
</head>
<body><img src="data:image1.jpg?tr=w-400,h-300" /><img src="data:image2.jpg?tr=w-400,h-300" /><img src="data:image3.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image2.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image3.jpg?tr=w-400,h-300" /> --><img class="lazy" src="data:image4.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image5.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image6.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image7.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image8.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image9.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image10.jpg?tr=w-400,h-300" /><script>document.addEventListener("DOMContentLoaded", function() {var lazyloadImages = document.querySelectorAll("img.lazy"); var lazyloadThrottleTimeout;function lazyload () {if(lazyloadThrottleTimeout) {clearTimeout(lazyloadThrottleTimeout);} lazyloadThrottleTimeout = setTimeout(function() {var scrollTop = window.pageYOffset;lazyloadImages.forEach(function(img) {if(img.offsetTop < (window.innerHeight + scrollTop)) {img.src = img.dataset.src;img.classList.remove('lazy');}});if(lazyloadImages.length == 0) {document.removeEventListener("scroll", lazyload);window.removeEventListener("resize", lazyload);window.removeEventListener("orientationChange", lazyload);}}, 20);}document.addEventListener("scroll", lazyload);window.addEventListener("resize", lazyload);window.addEventListener("orientationChange", lazyload);});</script>
</body>
</html>
- Intersection Observer(兼容性问题)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>observer</title><style>img {background: #F1F1FA;width: 400px;height: 300px;display: block;margin: 10px auto;border: 0;}</style>
</head>
<body><img src="data:image2.jpg?tr=w-400,h-300" /><img src="data:image3.jpg?tr=w-400,h-300" /> --><img class="lazy" src="data:image1.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image2.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image3.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image4.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image5.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image6.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image7.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image8.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image9.jpg?tr=w-400,h-300" /><img class="lazy" src="data:image10.jpg?tr=w-400,h-300" /><script>document.addEventListener("DOMContentLoaded", function() {var lazyloadImages = document.querySelectorAll(".lazy");var imageObserver = new IntersectionObserver(function(entries, observer) {entries.forEach(function(entry) {if (entry.isIntersecting) {var image = entry.target;image.src = image.dataset.src;image.classList.remove("lazy");imageObserver.unobserve(image);}});});lazyloadImages.forEach(function(image) {imageObserver.observe(image);});});</script>
</body>
</html>
background-image的实现
background-image的实现跟img的原理基本是一样的,区别是在对class的处理上:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>background</title><style>body {margin: 0;}.bg {height: 200px;}#bg-image.lazy {background-image: none;background-color: #F1F1FA;}#bg-image {background-image: url("image1.jpg?tr=w-400,h-300");background-size: 100%;}</style>
</head>
<body><div id="bg-image" class="bg lazy"></div><div id="bg-image" class="bg lazy"></div><div id="bg-image" class="bg lazy"></div><div id="bg-image" class="bg lazy"></div><div id="bg-image" class="bg lazy"></div><div id="bg-image" class="bg lazy"></div><div id="bg-image" class="bg lazy"></div><div id="bg-image" class="bg lazy"></div><script>document.addEventListener("DOMContentLoaded", function() {var lazyloadImages = document.querySelectorAll(".lazy");var imageObserver = new IntersectionObserver(function(entries, observer) {entries.forEach(function(entry) {if (entry.isIntersecting) {var image = entry.target;image.classList.remove("lazy");imageObserver.unobserve(image);}});});lazyloadImages.forEach(function(image) {imageObserver.observe(image);});});</script>
</body>
</html>
渐进式懒加载
渐进式懒加载,指的是存在降级处理,通常html形式如下:
<a href="full.jpg" class="progressive replace"><img src="tiny.jpg" class="preview" alt="image" />
</a>
这样的代码会有2个好处:
- 如果js执行失败,可以点击预览
- 大小与实际图一致的占位data URI,避免reflow
最终的代码如下:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>progressive</title><style>a.progressive {position: relative;display: block;overflow: hidden;outline: none;}a.progressive:not(.replace) {cursor: default;}a.progressive img {display: block;width: 100%;max-width: none;height: auto;border: 0 none;}a.progressive img.preview {filter: blur(2vw);transform: scale(1.05);}a.progressive img.reveal {position: absolute;left: 0;top: 0;will-change: transform, opacity;animation: reveal 1s ease-out;}@keyframes reveal {0% {transform: scale(1.05); opacity: 0;}100% {transform: scale(1); opacity: 1;}}</style>
</head>
<body><a href="nature5.jpg" data-srcset="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature5.jpg 800w, nature5big.jpg 1600w" class="progressive replace"><img src="https://img-blog.csdnimg.cn/2022010708094197492.jpeg" class="preview" alt="palm trees" /></a><a href="nature2.jpg" class="progressive replace"><img src="http://lorempixel.com/20/15/nature/2/" class="preview" alt="sunset" /></a><a href="nature3.jpg" class="progressive replace"><img src="http://lorempixel.com/20/15/nature/3/" class="preview" alt="tide" /></a><a href="nature5.jpg" data-srcset="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature5.jpg 800w, nature5big.jpg 1600w" class="progressive replace"><img src="https://img-blog.csdnimg.cn/2022010708094197492.jpeg" class="preview" alt="palm trees" /></a><a href="nature2.jpg" class="progressive replace"><img src="http://lorempixel.com/20/15/nature/2/" class="preview" alt="sunset" /></a><a href="nature3.jpg" class="progressive replace"><img src="http://lorempixel.com/20/15/nature/3/" class="preview" alt="tide" /></a><script>window.addEventListener('load', function() {var pItem = document.getElementsByClassName('progressive replace'), timer;window.addEventListener('scroll', scroller, false);window.addEventListener('resize', scroller, false);inView();function scroller(e) {timer = timer || setTimeout(function() {timer = null;requestAnimationFrame(inView);}, 300);}function inView() {var scrollTop = window.pageYOffset;var innerHeight = window.innerHeight;var p = 0;while (p < pItem.length) {var offsetTop = pItem[p].offsetTop;if (offsetTop < (scrollTop + innerHeight)) {loadFullImage(pItem[p]);pItem[p].classList.remove('replace');}else p++;}}function loadFullImage(item) {var img = new Image();if (item.dataset) {img.srcset = item.dataset.srcset || '';img.sizes = item.dataset.sizes || '';}img.src = item.href;img.className = 'reveal';if (img.complete) addImg();else img.onload = addImg;function addImg() {item.addEventListener('click', function(e) { e.preventDefault(); }, false);item.appendChild(img).addEventListener('animationend', function(e) {var pImg = item.querySelector('img.preview');if (pImg) {e.target.alt = pImg.alt || '';item.removeChild(pImg);e.target.classList.remove('reveal');}});}}}, false);</script>
</body>
</html>
现成库
推荐下面这个库,使用非常简单:https://www.npmjs.com/package/lozad
https://segmentfault.com/a/1190000017795499来源:
转载于:https://www.cnblogs.com/lalalagq/p/10241711.html
懒加载的3种实现方式相关推荐
- JS实现图片懒加载的几种简单方式,图片懒加载
记得以前手机端有个业务时将用户上传的的图片在用户往上滑动手机的时候呈现,由于刚开始用户数量少就没留意,直接将后台的数据拉过来渲染,当时后台也没有分页,可是后来参与用户多了起来,跳转到这个页面就渲染个几 ...
- vue项目实现路由按需加载(路由懒加载)的3种方式
vue项目实现路由按需加载(路由懒加载)的3种方式 1.vue异步组件 2.es提案的import() 3.webpack的require,ensur *1.vue异步组件技术 ==== 异步加载 v ...
- 实现图片懒加载的5种方式
目录 1.懒加载介绍 2.实现懒加载技术的方案 3.具体实现代码 1.懒加载介绍 当页面需要展示大量图片时,如果一次性渲染所有图片,会向服务器发出大量请求,导致服务器响应慢,出现页面卡顿或崩溃等问题. ...
- vue路由懒加载的两种方式
1.当一个vue项目很大的时候,对于一些"暂时"用不到的组件,我们可以不进行加载,等到用到次组件时再加载.这样可以优化spa应用首次加载白屏情况,也给用户更好的体验.这样就是vue ...
- js图片懒加载的第二种方式
这种方式是图片按照顺序一张一张的加载直到所有图片都加载完成 html 同样的要让图片进行懒加载,路径引用就得用 data-src <ul><li><img data-sr ...
- React ----- 路由懒加载的几种实现方案
传统的两种方式 1.import() 符合ECMAScript提议的import()语法,该提案与普通 import 语句或 require 函数的类似,但返回一个 Promise 对象.这意味着模块 ...
- 路由懒加载的三种写法
第一种懒加载方式: import Vue from 'vue' import Router from 'vue-router'const login= () => import('./compo ...
- 防抖与节流方案_关于图片懒加载的几种方案
作者: 山月行 转发链接:https://mp.weixin.qq.com/s/rY1LbW95LR6AqF1Vcx_d1Q 懒加载,顾名思义,在当前网页,滑动页面到能看到图片的时候再加载图片 故问题 ...
- 图片懒加载和Vue路由懒加载
图片懒加载 什么是懒加载? 懒加载也叫做延迟加载或者按需加载 .在长网页中延迟加载暂时未看到的图片数据,能够优化网页性能,提高用户体验 .在较长的网页或应用中,如果图片很多,等待全部图片都被加载出来需 ...
- Hibernate懒加载问题的5种解决方案
** 1.Hibernate基础 ** Hibernate基础,传送门 ** 2.什么是Hibernate懒加载 ** 当我们查询一个对象的时候,在默认情况下,返回的只是该对象的代理对象,当用户去使用 ...
最新文章
- 2019 ICPC Asia Nanjing Regional C.Digital Path(拓扑排序递推DP)
- vsftpd安装及虚拟用户认证
- auve子表单中只读不好用
- css制作漂亮彩带导航条菜单
- python多线程处理文件_python多线程分块读取文件
- 不需要定义神经网络结构就可以恢复模型的两方法
- Eclipse把默认为Gbk的编码变为UTF-8
- 算法总结-1算法入门
- leetcode —— 1025. 除数博弈
- matlab 拟合瑞利分布公式_概率论3「学生成绩转化」为正态分布和偏态分布的方法...
- windows查看本机的IP地址
- Python调用图灵机器人
- Random Features for Large-Scale Kernel Machines笔记
- android 系统重新安装,一招学会安卓手机系统重装教程
- 【Golang】JSON Marshal Unmarshal
- 介绍几种电路上常用的塑料插接件(1)
- 先进事迹如何写出深度?到底怎么做
- 技术支持岗位面试问题汇总,绝对有你遇到的面试题!!
- PIC18F47K42 初学篇-1
- 无需开通网银---银联快捷支付
热门文章
- 八点建议助您写出优雅的Java代码
- “12306”是如何支撑百万QPS的?
- 100 道 Linux 笔试题,能拿90分以上的都去了BAT
- java enable_Java Compiler enable()方法与示例
- python 如何封装dll_python怎么封装dll
- 苹果手机壳_潮牌刺绣苹果8 Plus手机壳,让爱机焕然一新
- shell初学之nginx(域名)
- oracle函数 NLS_INITCAP(x[,y])
- 刷面经笔记2019.01.30
- MySQL数据库操作(3)表结构操作