前端懒加载(Lazy Loading)实战指南

🚀 前端懒加载(Lazy Loading)实战指南

懒加载是现代 Web 性能优化的“常规操作”。它的目标简单直接:让用户只加载“当下真正需要的资源”。从静态资源、组件、模块到数据,每一层都可以使用懒加载技术,构建更快、更轻、更流畅的 Web 应用。


🧠 一、懒加载的本质是什么?

懒加载(Lazy Loading)= 按需加载 + 延迟执行

通俗地讲,它有以下几个目的:

问题懒加载如何解决
首屏加载慢不加载页面底部图片、非首屏组件
JS 包太大将 JS 拆分为多个小块,按需加载
用户未访问的内容占用资源延迟加载直到用户需要

本质上,它是时间与空间的优化交换,用“晚一点加载”换取“现在更快”。


🔥 二、六大常见懒加载场景详解

✅ 场景 1:图片懒加载(Lazy Image Loading)

📌 背景

图文混排页面中,图片往往占据大量流量资源,但用户可能根本不会滑到底部。

✅ 最佳方案:结合原生和 JS 手动方案

方法 1:原生 HTML 属性(推荐)

<img src="low-quality.jpg" loading="lazy" data-src="real-image.jpg"alt="文章配图" />
  • ✅ 优点:无需 JS,浏览器原生支持
  • ❗️缺点:旧版 Safari / IE 不支持

方法 2:JavaScript + IntersectionObserver

const imgs = document.querySelectorAll('img[data-src]');
const observer = new IntersectionObserver((entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {const img = entry.target;img.src = img.dataset.src;observer.unobserve(img);}});
});
imgs.forEach(img => observer.observe(img));

💡 小技巧:可结合 srcset 提供不同分辨率图像资源。

✅ 注意事项:
  • 图片应设置固定高度,防止懒加载后页面跳动(可用占位符)。
  • 可考虑加入淡入过渡动画提升体验。

✅ 场景 2:组件懒加载(Component Lazy Load)

📌 背景

单页应用中,许多组件(如弹窗、图表、用户详情)在初始页面并不会被立即使用。

📦 Vue 3 组件懒加载实现
import { defineAsyncComponent } from 'vue';const AsyncUserCard = defineAsyncComponent(() =>import('@/components/UserCard.vue')
);
<template><Suspense><template #default><AsyncUserCard /></template><template #fallback><div>加载中...</div></template></Suspense>
</template><script setup>
import AsyncUserCard from './AsyncUserCard.js';
</script>
🧠 思维方式:
  • 首屏核心内容同步加载。
  • 次要内容、低频交互使用懒加载(如 <Modal />, <Tabs />)。

✅ 场景 3:路由懒加载(Route-based Lazy Load)

📌 背景

SPA 中所有页面都打包进一个文件时,初始包极大,路由懒加载是首选优化手段。

🌿 Vue Router 懒加载
const routes = [{path: '/profile',component: () => import('@/views/Profile.vue')}
];

🧠 建议:

  • 首屏路由组件不应懒加载。
  • 子路由按需加载,特别是仪表盘类页面。

✅ 场景 4:第三方库懒加载(Third-Party Resource Lazy Load)

📌 背景

不常用但体积大的库(地图、图表、编辑器)应在用户真正需要时才加载。

示例:动态加载地图 SDK
// 懒加载高德地图 SDK(支持多次调用防重复加载)+ 使用方式示例
let amapLoaded = false, amapPromise = null;
export function loadAMapSDK() {return amapLoaded ? Promise.resolve(window.AMap) : (amapPromise ??= new Promise((resolve, reject) => {const script = document.createElement('script'); // 创建 <script> 标签script.src = 'https://webapi.amap.com/maps?v=1.4.15&key=你的Key'; // 设置 SDK 地址(替换你的 Key)script.onload = () => { amapLoaded = true; resolve(window.AMap); }; // 成功加载后 resolve AMapscript.onerror = () => reject(new Error('AMap SDK 加载失败')); // 加载失败时 rejectdocument.body.appendChild(script); // 将 script 添加到页面中触发加载}));
}// ✅ 使用方式(在需要加载地图的组件或函数中调用):
loadAMapSDK().then(AMap => {const map = new AMap.Map('mapContainer', { zoom: 10, center: [116.397428, 39.90923] }); // 创建地图实例
}).catch(err => {console.error('地图加载失败:', err); // 错误处理
});
适用库:
  • 高德/百度地图
  • echarts / chart.js
  • Monaco Editor(代码编辑器)
  • Quill / CKEditor(富文本)

✅ 场景 5:虚拟滚动(Virtual Scrolling)

📌 背景

一次性渲染几千条 DOM 会严重卡顿,虚拟滚动只渲染可视区域。

Vue 示例(使用 vue-virtual-scroller)
<RecycleScroller:items="items":item-size="60"key-field="id"
><template #default="{ item }"><div class="row">{{ item.name }}</div></template>
</RecycleScroller>
推荐库:
  • Vue:vue-virtual-scroller

✅ 场景 6:模块懒加载(Dynamic Module Import)

📌 背景

某些逻辑、库、工具仅在特定操作下触发,例如导出 Excel、打印页面等。

示例:点击导出按钮再导入模块
button.addEventListener('click', async () => {const { exportToExcel } = await import('./excel-utils.js');exportToExcel(data);
});
打包工具支持:
  • Webpack / Vite 都支持 import() 实现代码分割(Code Splitting)

🔍 三、不同懒加载方案对比

场景核心技术优势注意事项
图片loading="lazy" / JS简单高效,节省流量添加占位图,避免闪烁跳动
组件异步组件 / lazy降低首屏 JS 体积异步加载需提供 fallback UI
路由动态 import大型 SPA 性能优化利器不建议懒加载首屏页面
第三方资源动态添加 <script>避免加载无用资源注意资源重复加载与缓存控制
虚拟滚动可视区渲染支持大数据量流畅渲染容器尺寸需固定,高度计算精度
动态模块import() 动态导入极致按需,节省体积模块函数需异步封装

🛠️ 四、最佳实践 & 常见坑点

✅ 最佳实践汇总

类别实践建议
图片懒加载优先使用 loading="lazy",退级使用 IntersectionObserver,配合占位图防闪动
组件懒加载使用 defineAsyncComponent 配合 <Suspense> 显示 loading/error UI
路由懒加载首屏同步加载,次要页面用懒加载
模块懒加载import() 包装成 Promise,结合缓存避免重复请求
第三方资源createScript 懒加载,务必防止重复加载,可结合全局标记
虚拟滚动容器设置固定高度或使用 auto-resize 组件

⚠️ 常见坑点

  • 忘记处理加载失败:必须监听加载错误并提供提示
  • 首屏内容懒加载:会造成白屏、闪动,不推荐
  • 使用懒加载却不预设高度:会导致布局抖动
  • 路由懒加载组件打包失败:注意动态导入路径使用变量会导致无法分包
  • 动态模块未封装 Promise:可能导致并发问题或无法 await

📦 五、Vue 3 组件懒加载 Demo 示例

📁 文件结构:

src/
├── components/
│   └── HeavyComponent.vue
├── views/
│   └── HomeView.vue

HeavyComponent.vue

<template><div class="heavy">我是一个很重的组件,懒加载中...</div>
</template><script setup>
console.log('HeavyComponent 被加载了!');
</script><style scoped>
.heavy {padding: 20px;background-color: #f0f0f0;
}
</style>

HomeView.vue

<template><button @click="show = true">点击加载重组件</button><Suspense v-if="show"><template #default><HeavyComponent /></template><template #fallback><div>组件加载中...</div></template></Suspense>
</template><script setup>
import { ref, defineAsyncComponent } from 'vue';const show = ref(false);
const HeavyComponent = defineAsyncComponent(() =>import('@/components/HeavyComponent.vue')
);
</script>

📌 六、总结

懒加载是现代 Web 性能优化的重要利器,但也需结合实际场景“有策略地使用”:

  • 🔺 不要过度懒加载:首屏关键内容不应延迟。
  • 🔄 结合用户行为:滚动、点击、路由切换等时机才加载。
  • 🚧 一定要处理加载失败/超时场景
  • 🔧 使用 <Suspense> 显示加载状态,提高用户体验

记住这条铁律:**用户优先,体验至上,性能其次!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79826.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 Ubuntu 系统中,查看已安装程序的方法

在 Ubuntu 系统中&#xff0c;查看已安装程序的方法取决于软件的安装方式&#xff08;如通过 apt、snap、flatpak 或手动安装&#xff09;。以下是几种常见方法&#xff1a; 通过 apt 包管理器安装的软件 适用于通过 apt 或 dpkg 安装的 .deb 包。 列出所有已安装的软件包&…

性能优化实践:性能监控体系

性能优化实践&#xff1a;性能监控体系 在Flutter应用开发中&#xff0c;建立一个完善的性能监控体系对于保证应用质量和用户体验至关重要。本文将从实战角度深入讲解如何搭建Flutter应用的性能监控体系&#xff0c;包括监控指标的设计、数据采集实现、分析平台搭建等内容。 …

kotlin 02flow-sharedFlow 完整教程

一 sharedFlow是什么 SharedFlow 是 Kotlin 协程中 Flow 的一种 热流&#xff08;Hot Flow&#xff09;&#xff0c;用于在多个订阅者之间 共享事件或数据流。它适合处理 一次性事件&#xff08;如导航、弹窗、Toast、刷新通知等&#xff09;&#xff0c;而不是持续状态。 ✅ …

模拟开发授权平台

这次只是实现应用的curd和公私钥的校验以及第三方的通知dmeo项目&#xff0c;大家可以拓开视野来编写 进入主题 项目链接&#xff1a;桌角的眼镜/develop_auth_platform 直接下拉并运行就行 回调应用代码在test包中 回调应用测试代码 package mainimport ("encoding/…

STM32 USART串口

一、通信接口 二、串口通信 串口是一种应用十分广泛的通讯接口&#xff0c;串口成本低、容易使用、通信线路简单&#xff0c;可实现两个设备的互相通信单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信&#xff0c;极大地扩展了单片机的应用…

uniapp开发06-视频组件video的使用注意事项

uniapp开发-视频组件video的使用注意事项&#xff01;实际项目开发中&#xff0c;经常会遇到视频播放的业务需求。下面简单讲解一下&#xff0c;uniapp官方提供的视频播放组件video的常见参数和实际效果。 1&#xff1a;先看代码&#xff1a; <!--视频组件的使用展示-->…

【爬虫】微博热搜机

第一个下面一点&#xff1a; js代码&#xff1a; const n require("crypto-js");let s n.SHA1(n.enc.Utf8.parse("tSdGtmwh49BcR1irt18mxG41dGsBuGKS")) , a n.enc.Hex.parse(s.toString(n.enc.Hex).substr(0, 32));function h(t) {let e (i t Stri…

软考 系统架构设计师系列知识点之杂项集萃(51)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;50&#xff09; 第80题 设三个煤场A1、A2、A3分别能供应煤7、12、11万吨&#xff0c;三个工厂B1、B2、B3分别需要10、10、10万吨&#xff0c;从各煤场到各工厂运煤的单价&#xff08;百元/吨&…

npm,yarn,pnpm,cnpm,nvm,npx包管理器常用命令

前端比较主流的包管理器主要有三个npm&#xff0c;yarn&#xff0c;pnpm 多层级依赖&#xff0c;通常发生在依赖之间存在复杂的版本要求时 包 A 依赖于包 B1.0.0 包 B 依赖于包 C2.0.0 另一个包 D 也依赖于 C3.0.0 一、NPM (Node Package Manager) https://www.npmjs.cn/…

科普简洁版:同态加密——密码学的未来瑰宝

文章目录 一、同态加密的基本概念1.1 什么是同态加密1.2 同态加密的数学本质1.3 同态加密的类型 二、主要同态加密方案详解2.1 ElGamal加密2.2 Paillier加密2.3 Gentry的完全同态加密方案2.4 BGV方案2.5 BFV方案2.6 CKKS方案 三、同态加密的关键技术3.1 噪声管理技术3.2 多项式…

力扣第448场周赛

赛时成绩如下: 这应该是我力扣周赛的最好成绩了(虽然还是三题) 1. 两个数字的最大乘积 给定一个正整数 n。 返回 任意两位数字 相乘所得的 最大 乘积。 注意&#xff1a;如果某个数字在 n 中出现多次&#xff0c;你可以多次使用该数字。 示例 1&#xff1a; 输入&#xff1…

(一)Modular Monolith Architecture(项目结构/.net项目初始化/垂直切片架构)

文章目录 项目地址一、项目结构1.1 Modules1. Events 模块2. Users 模块3. Ticketing 模块4. Attendance 模块1.2 数据库模块1.3 模块架构选择1. 全是Clean Architecture2. 分别使用不同的架构二、初始化项目2.1 本地创建项目结构1. 创建空的solution2. 添加基础配置3. 创建git…

Java常用组件之Redis经典面试题(一)

大家好&#xff0c;今天为大家带来Java项目中&#xff0c;几乎必不可少的组件之一-Redis的一些常见面试题&#xff0c;帮忙近期需要面试的朋友们来一个理论基础突击&#xff01; 一、数据类型 1.Redis的常用数据类型有哪些 ? 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;…

2025.5.4总结

今天去光谷步行街逛了一下&#xff0c;感觉熟悉又陌生&#xff0c;说熟悉是因为初二的时候来过武汉光谷&#xff0c;尽管过去了8年时间&#xff0c;但丝毫不影响标志性建筑的存在&#xff0c;也陌生是商场的建筑风格真实气派&#xff0c;感觉进入了一座城堡&#xff0c;在里面都…

神经网络在专家系统中的应用:从符号逻辑到连接主义的融合创新

自人工智能作为一个学科面世以来&#xff0c;关于它的研究途径就存在两种不同的观点。一种观点主张对人脑的结构及机理开展研究&#xff0c;并通过大规模集成简单信息处理单元来模拟人脑对信息的处理&#xff0c;神经网络是这一观点的代表。关于这方面的研究一般被称为连接机制…

Doo全自动手机壳定制系统

Doo全自动手机壳定制系统 项目概述 Doo全自动手机壳定制系统是一个完整的手机壳定制解决方案&#xff0c;支持多端应用&#xff0c;包括服务端、客户端、管理后台等多个组件。系统采用现代化的技术栈&#xff0c;提供完整的手机壳定制、订单管理、用户管理等功能。 目录结构…

PageOffice在线打开word文件,并实现切换文件

本示例关键代码的编写位置&#xff0c;请参考“PageOffice 开发者中心-快速起步–开始 - 快速上手”里您所使用的开发语言框架的最简集成代码 注意 本文中展示的代码均为关键代码&#xff0c;复制粘贴到您的项目中&#xff0c;按照实际的情况&#xff0c;例如文档路径&#xff…

Webug4.0靶场通关笔记12- 第17关 文件上传之前端拦截(3种方法)

目录 一、文件上传前端拦截原理 二、第17关 文件上传(前端拦截) 1.打开靶场 2.构造php脚本 3.源码分析 &#xff08;1&#xff09;js源码 &#xff08;2&#xff09;服务器源码 &#xff08;3&#xff09;总结 4.渗透实战 &#xff08;1&#xff09;禁用js法 &#…

高性能 WEB 服务器 Nginx:多虚拟主机实现!

Nginx 配置多虚拟主机实现 多虚拟主机是指在一台 Nginx 服务器上配置多个网站 在 Nginx 中&#xff0c;多虚拟主机有三种实现方式&#xff1a; 基于IP地址实现多虚拟主机 基于端口号实现多虚拟主机 基于域名实现多虚拟主机 1 基于域名实现多虚拟主机 在 Nginx 中配置多个…

网星安全AWS攻防方案,重磅发布!

AWS介绍 AWS&#xff08;Amazon Web Services&#xff09; 是 Amazon 提供的云计算平台&#xff0c;提供了广泛的云服务&#xff0c;包括计算、存储、数据库、网络、安全、人工智能、大数据处理等功能&#xff0c;帮助企业和开发者构建、部署和管理应用程序。AWS 是全球最大的…