17370845950

JavaScript如何实现惰性加载_怎样优化页面加载性能
惰性加载的核心是推迟非首屏资源加载至用户需要时:原生支持loading="lazy";JS推荐IntersectionObserver监听视口;动态import实现代码分割;需配合占位、加载态与预加载优化体验。

JavaScript 实现惰性加载(Lazy Loading)的核心思路是:**推迟非首屏资源的加载,直到用户真正需要时再触发**。这能显著减少初始页面体积、缩短白屏时间、降低带宽消耗,尤其对图片、视频、组件、路由等资源效果明显。

图片和 iframe 的原生惰性加载

现代浏览器已支持 loading="lazy" 属性,无需 JavaScript 即可实现基础惰性加载:

  • 图片
  • iframe

注意:该属性在 Chrome 76+、Firefox 75+、Safari 15.4+ 中支持;不支持时会自动降级为正常加载,安全可靠。

使用 IntersectionObserver 监听可视区域

这是最常用、性能最优的 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));

动态导入(Dynamic Import)实现代码分割

对 JS 模块或组件做惰性加载,适用于路由切换、弹窗、折叠面板等场景:

  • import()(返回 Promise)替代静态 import,让模块按需下载执行
  • React 中配合 React.lazy() + Suspense 加载组件
  • Vue 中用 defineAsyncComponent 或直接 import() 返回组件

例如路由级懒加载(Vue Router):

const routes = [
  { path: '/about', component: () => import('./views/About.vue') }
];

结合占位与加载状态提升体验

纯技术懒加载不够,还需优化用户体验:

  • 为图片预留宽高或使用骨架屏(Skeleton),防止布局偏移(CLS)
  • 添加加载中状态(如淡入动画、loading 图标),避免空白等待
  • 预加载关键资源(如首屏图片)可用 ,与懒加载互补

不复杂但容易忽略。