前端代码按需加载(懒加载)的实现方案

 更新时间:2025年06月23日 11:00:34   作者:破碎的天堂鸟  
懒加载也叫做延迟加载、按需加载,指的是在长网页中延迟加载图片数据,是一种较好的网页性能优化的方式,那么如何实现前端代码的按需加载(懒加载)呢,本文给大家介绍了三种实现方式,需要的朋友可以参考下

一、技术原理与核心价值

懒加载(Lazy Loading)是一种通过延迟非关键资源加载以提升网页性能的技术,其核心原理是按需动态加载资源,而非一次性加载所有内容。其价值体现在:

  • 性能优化:减少初始加载资源量,缩短首屏渲染时间(FCP)和可交互时间(TTI)。
  • 资源节约:节省带宽和服务器资源,避免加载用户未访问的内容。
  • 体验提升:防止大量资源并发加载导致页面卡顿,保持交互流畅性。

二、主流实现方式

1. 原生JavaScript实现

(1)传统滚动监听方案

原理:通过监听scroll事件,计算元素是否进入视口(Viewport)。

关键代码

function isInViewport(element) {
  const rect = element.getBoundingClientRect();
  return (
    rect.top <= window.innerHeight && 
    rect.bottom >= 0
  );
}
window.addEventListener('scroll', () => {
  images.forEach(img => {
    if (isInViewport(img)) {
      img.src = img.dataset.src; // 替换data属性为真实路径
    }
  });
});

缺点:频繁触发scroll事件可能导致性能问题,需结合防抖(debounce)优化。

(2)Intersection Observer API

原理:浏览器原生API,高效监听元素与视口的交叉状态。

代码示例

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img); // 加载后停止观察
    }
  });
}, { threshold: 0.1 }); // 设置触发阈值
 
document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));

优势:性能更优,避免手动计算和频繁事件触发。

(3)原生loading="lazy"属性

实现方式:直接为<img><iframe>添加属性:

<img src="placeholder.jpg" data-src="real-image.jpg" loading="lazy">

兼容性:Chrome 76+、Firefox 75+支持,不支持的浏览器自动回退为即时加载。

2. 框架级实现方案

React

组件懒加载

import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./Component'));
function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

路由懒加载(结合React Router):

import { createBrowserRouter } from 'react-router-dom';
const AdminPage = React.lazy(() => import('./AdminPage'));
const router = createBrowserRouter([
  { path: '/admin', element: <AdminPage /> }
]);

通过React.lazy与动态import()实现代码分割,按需加载路由组件。

Vue

图片懒加载(使用vue-lazyload插件):

// main.js
import VueLazyload from 'vue-lazyload';
Vue.use(VueLazyload, {
  preLoad: 1.3,
  error: 'error.png',
  loading: 'loading.gif'
});
 
// 组件中
<img v-lazy="imageUrl">

路由懒加载

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

通过Webpack自动分割代码块。

3. 构建工具支持(Webpack)

动态导入(Dynamic Import)

button.addEventListener('click', () => {
  import('./module.js').then(module => module.doSomething());
});

魔法注释(Magic Comments) 指定Chunk名称:

import(/* webpackChunkName: "lodash" */ 'lodash').then(_ => {...});

SplitChunksPlugin:自动拆分公共依赖,避免重复加载。

三、性能优化策略

  • 预加载关键资源:结合<link rel="preload">提前加载首屏必要资源,平衡懒加载与首屏速度。
  • 占位符设计
    • 使用固定宽高或aspect-ratio避免布局抖动。
    • 加载前显示低分辨率占位图(LQIP)或骨架屏。
  • 加载优先级控制
    • 设置threshold参数提前加载(如threshold: 0.1表示元素进入视口10%时触发)。
    • 避免过度懒加载影响用户滚动体验。

四、常见问题与解决方案

问题场景解决方案
SEO不友好使用<noscript>标签提供备用内容,或服务端渲染(SSR)关键内容
图片重复加载加载后移除data-src属性或取消Intersection Observer监听
浏览器兼容性使用Polyfill(如intersection-observer)或降级为传统滚动监听
滚动卡顿优化scroll事件处理(防抖/节流),或改用Intersection Observer
布局抖动(CLS)设置固定占位高度,或使用CSS aspect-ratio

五、未来趋势与扩展

  • 预测性加载:结合机器学习预测用户行为,提前加载可能访问的资源。
  • 标准化增强:更多浏览器支持loading="lazy",逐步替代JavaScript方案。
  • 框架深度整合:React 18+的并发模式(Concurrent Mode)支持更细粒度的懒加载控制。

总结

懒加载是提升前端性能的关键技术,需根据场景选择实现方式:

  • 简单场景:优先使用loading="lazy"或Intersection Observer API。
  • 复杂应用:结合框架(React/Vue)的懒加载组件与Webpack代码分割。
  • 兼容性要求高:采用Polyfill与渐进增强策略。

最终目标是在减少初始负载的同时,保持用户体验的流畅性,避免过度优化导致的负面效果。

到此这篇关于前端代码按需加载(懒加载)的实现方案的文章就介绍到这了,更多相关前端代码按需加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • EasyUi中的Combogrid 实现分页和动态搜索远程数据

    EasyUi中的Combogrid 实现分页和动态搜索远程数据

    jquery easyui中的combogrid比较特殊,算是combo和grid的组合,combogrid结合一个可编辑的文本框和下拉数据网格面板,可以让用户迅速找到并选择,又可以进行搜索,展示与当前输入的字符相匹配的数据。下面给大家介绍EasyUi中的Combogrid 实现分页和动态搜索远程数据
    2016-04-04
  • JS实现css hover操作的方法示例

    JS实现css hover操作的方法示例

    这篇文章主要介绍了JS实现css hover操作的方法,涉及javascript事件响应及页面元素css属性动态操作相关技巧,需要的朋友可以参考下
    2017-04-04
  • webpack-dev-server搭建本地服务器的实现

    webpack-dev-server搭建本地服务器的实现

    当我们使用webpack打包时,发现每次更新了一点代码,都需要重新打包,我们希望本地能搭建一个服务器,本文就介绍如何使用webpack-dev-server搭建本地服务器,感兴趣的可以了解一下
    2021-07-07
  • JS实现星星海特效

    JS实现星星海特效

    这篇文章主要为大家详细介绍了JS实现星星海特效特效,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • ie8下修改input的type属性报错的解决方法

    ie8下修改input的type属性报错的解决方法

    当用户勾选显示明文复选框时,要以明文显示用户输入的密码,去掉勾选时要变回密文,问题是ie8中是不允许修改input的type属性
    2014-09-09
  • js实现遮罩层弹出框的方法

    js实现遮罩层弹出框的方法

    这篇文章主要介绍了js实现遮罩层弹出框的方法,可实现对遮罩层弹出框的样式定义、按钮事件及相关功能的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • JS/jQ实现免费获取手机验证码倒计时效果

    JS/jQ实现免费获取手机验证码倒计时效果

    这篇文章主要介绍了JS/jQ实现免费获取手机验证码倒计时效果的相关资料,通过定义两个接口,发送验证请求和返回数据验证手机号和验证是否一致,后台根据接口去实现,需要的朋友可以参考下
    2016-06-06
  • Js中async/await的执行顺序详解

    Js中async/await的执行顺序详解

    随着async/await正式纳入ES7标准,越来越多的人开始研究据说是异步编程终级解决方案的 async/await。下面这篇文章主要给大家介绍了关于Js中async/await执行顺序的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • JavaScript实现标签页切换效果

    JavaScript实现标签页切换效果

    这篇文章主要为大家详细介绍了JavaScript实现标签页切换效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • javascript合并两个数组最简单的实现方法

    javascript合并两个数组最简单的实现方法

    这篇文章主要介绍了javascript合并两个数组最简单的实现方法,方法很简单,有需要的朋友们可以学习下。
    2019-09-09

最新评论