惰性加载的核心是推迟非首屏资源加载至用户需要时:原生支持loading="lazy";JS推荐IntersectionObserver监听视口;动态import实现代码分割;需配合占位、加载态与预加载优化体验。
JavaScript 实现惰性加载(Lazy Loading)的核心思路是:**推迟非首屏资源的加载,直到用户真正需要时再触发**。这能显著减少初始页面体积、缩短白屏时间、降低带宽消耗,尤其对图片、视频、组件、路由等资源效果明显。
现代浏览器已支持 loading="lazy" 属性,无需 JavaScript 即可实现基础惰性加载:
注意:该属性在 Chrome 76+、Firefox 75+、Safari 15.4+ 中支持;不支持时会自动降级为正常加载,安全可靠。
这是最常用、性能最优的 JS 惰性加载方案,比监听 scroll 事件更高效(不触发重排重绘、支持被动监听):
IntersectionObserver 实例,设定阈值(如 { threshold: 0.1 } 表示元素 10% 进入视口即触发)data-src 存真实地址的 ),调用 observer.observe(el)
el.dataset.src 赋给 el.src,并取消监听(避免重复加载)示例关键代码:
const lazyImages = document.querySelectorAll('img[data-src]');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.removeAttribute('data-src');
observer.unobserve(img);
}
});
}, { threshold: 0.1 });
lazyImages.forEach(img => observer.observe(img));
对 JS 模块或组件做惰性加载,适用于路由切换、弹窗、折叠面板等场景:
import()(返回 Promise)替代静态 import,让模块按需下载执行React.lazy() + Suspense 加载
组件defineAsyncComponent 或直接 import() 返回组件例如路由级懒加载(Vue Router):
const routes = [
{ path: '/about', component: () => import('./views/About.vue') }
];
纯技术懒加载不够,还需优化用户体验:
,与懒加载互补不复杂但容易忽略。