以下回答主要由 Deepseek AI 生成,经博主本人审核和增删整理,如有错漏请评论区反馈。
JavaScript 懒加载全面总结
懒加载基础概念
| 项目 | 描述 | 示例 |
|---|---|---|
| 定义 | 延迟加载资源的技术,只在需要时才加载 | 图片进入视口时再加载 |
| 核心思想 | "按需加载",减少初始加载时间和资源消耗 | 不立即加载所有资源 |
| 对立概念 | 饥饿加载(Eager Loading) | 页面加载时立即获取所有资源 |
| 适用场景 | 图片、视频、代码分割、第三方库等 | 非关键资源延迟加载 |
懒加载的实现原理
| 原理 | 技术手段 | 检测时机 |
|---|---|---|
| 视口检测 | Intersection Observer API | 元素进入可视区域时 |
| 滚动事件 | 监听 scroll 事件 + 位置计算 | 用户滚动时检查 |
| 手动触发 | 用户交互(点击、hover等) | 特定动作发生时 |
| 条件加载 | 基于设备、网络等条件 | 满足特定条件时 |
不同类型的懒加载
图片懒加载
// 使用 Intersection Observer(现代方式)
const lazyImages = document.querySelectorAll('img[data-src]');
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
imageObserver.unobserve(img);
}
});
});
lazyImages.forEach(img => imageObserver.observe(img));
代码分割懒加载
// 动态 import() - 组件懒加载
const LazyComponent = React.lazy(() => import('./ExpensiveComponent'));
// 路由懒加载
const routes = [
{
path: '/admin',
component: () => import('./AdminPanel')
}
];
第三方库懒加载
// 按需加载第三方库
async function loadAnalytics() {
if (userConsented) {
const { Analytics } = await import('analytics-library');
Analytics.track('page_view');
}
}
懒加载的实现方式对比
| 实现方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Intersection Observer | 高性能,不阻塞主线程 | 兼容性需要处理 | 图片、广告等可视区域检测 |
| Scroll 事件监听 | 兼容性好 | 性能较差,需要防抖 | 传统浏览器支持 |
| 动态 import() | 原生支持,代码分割 | 需要构建工具配合 | 路由、组件懒加载 |
| 手动触发 | 完全控制加载时机 | 需要用户交互 | 模态框、复杂功能 |
图片懒加载详细实现
HTML 结构
<!-- 懒加载图片 -->
<img
data-src="real-image.jpg"
src="placeholder.jpg"
alt="描述"
class="lazy-image"
loading="lazy" <!-- 原生懒加载 -->
>
<!-- 懒加载背景图 -->
<div
class="lazy-bg"
data-bg="background-image.jpg"
style="background-image: url('placeholder.jpg')"
></div>
完整实现方案
class LazyLoader {
constructor() {
this.images = [];
this.init();
}
init() {
if ('IntersectionObserver' in window) {
this.initWithObserver();
} else {
this.initWithScroll();
}
}
initWithObserver() {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.loadImage(entry.target);
observer.unobserve(entry.target);
}
});
}, { rootMargin: '50px' }); // 提前50px加载
document.querySelectorAll('[data-src], [data-bg]').forEach(el => {
observer.observe(el);
});
}
initWithScroll() {
this.images = Array.from(document.querySelectorAll('[data-src], [data-bg]'));
this.checkImages();
// 防抖滚动监听
const check = () => this.checkImages();
window.addEventListener('scroll', check);
window.addEventListener('resize', check);
}
checkImages() {
this.images = this.images.filter(img => {
if (this.isInViewport(img)) {
this.loadImage(img);
return false; // 从数组中移除
}
return true;
});
if (this.images.length === 0) {
window.removeEventListener('scroll', this.checkImages);
}
}
isInViewport(element) {
const rect = element.getBoundingClientRect();
return (
rect.top <= window.innerHeight &&
rect.bottom >= 0 &&
rect.left <= window.innerWidth &&
rect.right >= 0
);
}
loadImage(element) {
if (element.dataset.src) {
element.src = element.dataset.src;
element.removeAttribute('data-src');
}
if (element.dataset.bg) {
element.style.backgroundImage = `url(${element.dataset.bg})`;
element.removeAttribute('data-bg');
}
}
}
// 初始化
new LazyLoader();
性能优化策略
| 策略 | 实现方式 | 效果 |
|---|---|---|
| 预连接 | <link rel="preconnect"> |
提前建立连接 |
| 预加载关键资源 | <link rel="preload"> |
优先加载关键资源 |
| 懒加载非关键资源 | 上述懒加载技术 | 减少初始负载 |
| 响应式图片 | srcset + sizes |
按设备加载合适尺寸 |
| 渐进加载 | 低质量图片占位 → 高质量 | 更好的用户体验 |
浏览器原生懒加载
loading="lazy" 属性
<!-- 原生图片懒加载 -->
<img
src="image.jpg"
loading="lazy"
alt="描述"
>
<!-- iframe 懒加载 -->
<iframe
src="content.html"
loading="lazy"
></iframe>
原生懒加载支持情况
| 浏览器 | 支持版本 | 备注 |
|---|---|---|
| Chrome | 76+ | 全面支持 |
| Firefox | 75+ | 支持 |
| Safari | 15.4+ | 支持 |
| Edge | 79+ | 基于 Chromium |
最佳实践
| 实践 | 说明 | 理由 |
|---|---|---|
| 设置合适的阈值 | 提前 50-100px 开始加载 | 避免用户等待 |
| 提供占位符 | 使用低质量图片或纯色背景 | 保持布局稳定 |
| 错误处理 | 加载失败时显示备用内容 | 提升用户体验 |
| 性能监控 | 测量懒加载效果 | 持续优化 |
| 渐进增强 | 支持原生懒加载,降级到 JS 方案 | 兼容所有用户 |
懒加载的收益
| 指标 | 改善效果 | 测量方式 |
|---|---|---|
| 首次加载时间 | 减少 20-60% | Lighthouse |
| 首次内容绘制 | 显著提升 | FCP 指标 |
| 页面重量 | 减少初始下载量 | 网络面板 |
| 用户体验 | 更快的可交互时间 | 用户反馈 |
懒加载是现代 Web 性能优化的核心技术之一,通过合理延迟非关键资源的加载,可以显著提升页面加载性能和用户体验。