当前位置: 首页 > news >正文

解锁懒加载:提升性能的神奇魔法

一、什么是懒加载

懒加载是一种资源加载优化技术,核心是 “按需加载”,只在资源即将进入视野时才加载。

二、懒加载的作用

  • 减少初始加载时间,提升页面打开速度。
  • 降低服务器初始请求压力,节省带宽资源。
  • 减少设备内存占用,提升页面运行流畅度。

三、常见应用场景

  • 长列表页面(如商品列表、资讯流)的图片加载。
  • 包含大量视频的页面(仅加载当前可视区域视频)。
  • 非首屏的组件或脚本(如底部评论区、统计脚本)。

四、懒加载的实现原理

懒加载的核心实现原理可以概括为 “延迟加载 + 条件触发”—— 初始不加载非必要资源,通过监听特定事件判断资源是否 “即将被使用”,满足条件时再动态加载资源。

具体拆解为 4 个关键步骤,结合技术细节和逻辑闭环说明:

1、核心前提:资源 “占位” 与初始状态标记

懒加载的第一步是让浏览器不主动加载目标资源,同时预留资源位置避免页面布局抖动:

1.1 不直接赋值资源地址:

比如图片,不把真实地址写在 src 属性(src 会触发浏览器自动加载),而是存到自定义属性(如 data-src、data-original);视频同理,不设置 src 或 source 的 src,改用自定义属性存储真实地址。

<!-- 图片懒加载示例:初始不加载,真实地址存在 data-src -->
<img class="lazy" data-src="真实图片地址.jpg" alt="示例" width="300" height="200">
1.2 预留布局空间:

通过 width/height 属性或 CSS 固定资源尺寸(如 aspect-ratio),避免资源加载后页面重排(回流)。

2、关键步骤:监听 “触发条件” 事件

要判断资源 “是否即将被访问”,需要监听用户行为或页面状态变化,常见触发事件有 3 类:

2.1 滚动事件(最常用):

监听 window.scroll 事件(或元素的 scroll 事件,如滚动容器内的资源),实时判断资源位置。

❗ 优化点:用 throttle(节流)限制事件触发频率(如 100ms 触发一次),避免滚动时频繁计算导致性能消耗。

2.2 视口交叉检测(现代方案):

使用 Intersection Observer API(浏览器原生 API),无需手动监听滚动,直接检测 “资源元素是否进入视口(或与视口交叉)”,性能更优、代码更简洁。

2.3 其他触发场景:

点击事件(如点击 “加载更多” 时加载下方资源);

页面加载完成后的初始检测(首屏内的 “懒加载资源” 需要初始判断是否在视口,避免漏加载)。

3、核心逻辑:判断 “是否需要加载”

通过事件触发后,计算资源位置与视口的关系,核心判断条件是:资源是否进入视口,或即将进入视口(预留缓冲)

3.1 传统计算方式(手动判断)

通过 getBoundingClientRect() 获取元素的位置信息,结合视口高度 / 宽度判断:

  • 元素顶部距离视口顶部的距离(element.top)≤ 视口高度(window.innerHeight)+ 缓冲距离(如 200px,提前加载,避免用户看到空白);
  • 元素左侧距离视口左侧的距离(element.left)≤ 视口宽度(window.innerWidth)+ 缓冲距离(适配横向滚动场景)。

核心计算代码示例:

function isInViewport(element) {const rect = element.getBoundingClientRect();const viewportHeight = window.innerHeight || document.documentElement.clientHeight;const viewportWidth = window.innerWidth || document.documentElement.clientWidth;const buffer = 200; // 提前200px加载,提升体验// 元素顶部进入视口(含缓冲),且元素左侧在视口内return rect.top <= viewportHeight + buffer && rect.left <= viewportWidth + buffer;
}
3.2 现代方案(Intersection Observer)

无需手动计算,API 自动监听元素与视口的 “交叉状态”:

  • 定义一个观察者(Observer),指定交叉阈值(如元素进入视口 10% 时触发);
  • 当元素满足交叉条件时,触发回调函数,执行加载逻辑。

4、最终动作:动态加载资源并 “解锁”

当资源满足加载条件时,执行真正的加载操作,同时避免重复加载:

4.1 动态赋值真实地址:

把自定义属性(data-src)的值赋给原生属性(src),浏览器会自动发起请求加载资源;
视频需创建 source 元素并赋值 src,或直接修改视频 src。

4.2 标记 “已加载”,避免重复处理:

加载后移除 lazy 类或添加 loaded 类,后续事件触发时跳过已加载的资源。

4.3 清理监听(可选):

若资源加载后不会再 “离开视口并需要重新加载”(如长列表图片),可停止监听该元素(如 Intersection Observer 调用 unobserve),减少性能消耗。

<!-- 1. 初始占位 -->
<img class="lazy" data-src="image1.jpg" alt="示例" width="300" height="200">
<img class="lazy" data-src="image2.jpg" alt="示例" width="300" height="200"><script>
// 2. 监听触发事件(以 Intersection Observer 为例)
const lazyImages = document.querySelectorAll('.lazy');// 3. 定义加载逻辑
function loadImage(img) {if (img.dataset.src) {img.src = img.dataset.src; // 动态赋值,触发加载img.removeAttribute('data-src'); // 移除自定义属性img.classList.add('loaded'); // 标记已加载}
}// 4. 创建观察者,判断交叉条件
const observer = new IntersectionObserver((entries) => {entries.forEach(entry => {if (entry.isIntersecting) { // 元素进入视口loadImage(entry.target); // 加载资源observer.unobserve(entry.target); // 停止监听该元素}});
}, { rootMargin: '200px' }); // 预留200px缓冲,提前加载// 5. 对所有懒加载图片启动监听
lazyImages.forEach(img => observer.observe(img));
</script>

5、核心总结

懒加载的实现原理本质是:“先占位不加载 → 监听触发事件 → 判断是否进入视口(含缓冲) → 动态加载资源并标记”
其中,Intersection Observer 是现代浏览器推荐方案(性能优、代码简洁),传统滚动 + 手动计算适用于需要兼容旧浏览器的场景。

五、懒加载实现代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script><title>Document</title><style>
.bg,.bg1,.small,.big{overflow: hidden;width: 100%;height: 800px;background-size: cover; /* 保留原有样式 */background-repeat: no-repeat;background-position: center center;
}</style>
</head>
<body>
<div class="bg" data-bg="https://b0.bdstatic.com/ugc/7vzLq4vmPMp_X3SVZJaslg0ea528533a78abb146f8d2c8426b952d.jpg"></div>
<div class="bg1" data-bg="https://img0.baidu.com/it/u=894097787,217968889&fm=253&app=138&f=JPEG?w=500&h=889"></div>
<div class="small" data-bg="https://pic.rmb.bdstatic.com/bjh/3f11932f0ab1/250105/8cf77de872c0c4fc63b96b7a9679d3fe.jpeg"></div>
<div class="big" data-bg="https://pics4.baidu.com/feed/ae51f3deb48f8c54a4a7709a9ce510fae1fe7f6e.jpeg@f_auto?token=284dceaa76d389c9c4bc2632df15a9c1"></div>
<script>// 等待页面DOM加载完成
$(document).ready(function() {// 定义懒加载函数function lazyLoad() {// 1. 处理img标签(logo、秒杀图标等)$("img[data-src]").each(function() {const $img = $(this);// 判断元素是否进入可视区域if (isInViewport($img)) {$img.attr("src", $img.data("src")).removeAttr("data-src"); // 加载图片并移除自定义属性}});// 2. 处理背景图(大背景、商品卡片背景等)$("[data-bg]").each(function() {const $el = $(this);if (isInViewport($el)) {$el.css("background-image", `url(${ $el.data("bg") })`).removeAttr("data-bg"); // 加载背景图}});}// 辅助函数:判断元素是否在可视区域内function isInViewport($el) {const rect = $el[0].getBoundingClientRect();// 元素顶部进入视口底部,或元素底部进入视口顶部,即判定为可见return (rect.top <= $(window).height() + 100 && // 提前100px加载,避免滚动时空白rect.bottom >= 0);}// 初始加载一次(加载首屏可见元素)lazyLoad();// 监听滚动事件,触发懒加载$(window).scroll(function() {lazyLoad();});// 监听窗口 resize 事件(适配屏幕变化)$(window).resize(function() {lazyLoad();});
});
</script>
</body>
</html>
http://www.dtcms.com/a/598883.html

相关文章:

  • 那里可以做PC28网站的好看的 网站正在建设中源码
  • Vue项目集成bootstrap步骤及动态静态修改属性样式完整示例
  • 个人网站设计分析上海高玩seo
  • 大型门户网站建设是什么wordpress首页透明
  • 织梦做网站的教程惠州做网站广告
  • 做58同城这样的网站delphi网站开发教程
  • 《中医基础理论》- 番外篇-五神脏详解
  • 简述网站一般建设的流程图济南建设设备安装有限责任公司官网
  • 规划建立一个网站 项目成品网站nike源码1688
  • 广州网站建设公司网络安全优化中企动力北京总部地址
  • JavaScript基础知识总结(五)面向对象与原型,深浅拷贝,防抖节流
  • 韶关市住房和城乡建设局网站有限责任公司章程
  • 网站设计费报价表国际军事新闻最新消息
  • wls科普
  • 设计未来,解锁云端高效创作新纪元
  • 广州好的网站设计公司淘宝的网站是怎么做的
  • 网站制作大型公司龙华专业做网站公司
  • 在线 IP 查询如何做到更准确——选站、比对、校验全流程解析
  • 网络设计课程中对网页设计的报告临沂seo公司稳健火星
  • SiC MOS功率模块的并联均流技术
  • 做淘客网站需要备案南阳那里有做网站的
  • CPRI与OBSAI接口技术介绍
  • 简单的网站构建的基本流程西部空间官方网站
  • 如何在SourceForge上找到其他项目的下载链接?
  • 网络公司发生网站建设费分录学生个人网站作品
  • P4766 [CERC2014] Outer space invaders
  • 怎么在传奇网站上做宣传网站能不能用自己的电脑做服务器
  • web服务器
  • 个人建设网站服务器怎么解决方案东营房产网
  • 菏泽兼职网站建设wordpress登陆页面修改