刷刷题38(前端实现分包及组件懒加载的核心方案&&图片懒加载)

组件懒加载

一、路由级懒加载(框架原生支持)

  1. Vue Router 动态导入

    使用 import() 语法实现路由级代码分割,访问对应路由时加载独立分包‌。

javascript 复制代码
const router = new VueRouter({
  routes: [
    { path: '/about', component: () => import('./views/About.vue') } // 生成独立 chunk
  ]
});

React Router v6+ 方案

结合 React.lazySuspense 实现按需加载‌:

javascript 复制代码
const Home = React.lazy(() => import('./components/Home'));
<Suspense fallback={<Loading />}>
  <Route path="/home" element={<Home />} />
</Suspense>

二、组件级懒加载(细粒度优化)

  1. 动态导入语法

    在组件使用前通过 import() 延迟加载,适用于弹窗等非首屏内容‌:

javascript 复制代码
// Vue
const Dialog = () => import('./Dialog.vue');

// React
const Editor = React.lazy(() => import('./Editor'));

条件触发加载

结合用户交互(如点击按钮)触发组件加载‌:

java 复制代码
function loadComponent() {
  import('./ChartComponent').then(module => {
    const Chart = module.default;
    // 渲染组件
  });
}

三、构建工具配置(底层支持)

  1. Webpack 代码分割

    • 通过 splitChunks 配置公共模块分包‌:
css 复制代码
optimization: {
  splitChunks: {
    chunks: 'all',
    cacheGroups: {
      vendor: { test: /node_modules/, name: 'vendors' }
    }
  }
}
  • 使用 /* webpackChunkName: "chunk-name" */ 自定义分包名称‌。
  1. Vite 自动分包

    动态导入自动生成独立 chunk,无需额外配置‌。

    四、优化策略

  2. 预加载关键资源

    对高优先级分包添加 webpackPreload 注释,提前加载‌:

go 复制代码
import(/* webpackPreload: true */ './CriticalComponent');
  1. 缓存优化

    • 分包命名包含哈希值(如 [contenthash]),利用浏览器长效缓存‌。
    • Webpack 5 配置 cache: { type: 'filesystem' } 加速二次构建‌。

错误处理与降级

封装加载逻辑,捕获网络异常并提供重试机制‌:

javascript 复制代码
const loadWithRetry = async (url, retries = 3) => {
  try {
    return await import(url);
  } catch (err) {
    if (retries > 0) return loadWithRetry(url, retries - 1);
    throw err;
  }
};

总结

前端实现懒加载需结合框架特性与构建工具:

  1. 路由/组件级动态导入‌ 触发自动分包(Vue/React 原生支持)‌;
  2. 构建配置‌ 优化拆分策略(Webpack/Vite 定制化)‌;
  3. 预加载+缓存 ‌ 平衡性能与用户体验‌。
    通过分层加载策略,可降低首屏资源体积 30%~50%‌34,显著提升交互响应速度。

图片的懒加载

一使用第三方库 vue-lazyload

适用场景 ‌:需要快速集成和丰富功能(加载态、错误处理)

实现步骤‌:

  1. 安装依赖

    npm install vue-lazyload

全局配置

javascript 复制代码
// main.js
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload, {
  preLoad: 1.3, // 预加载高度比例
  error: require('@/assets/error.png'), // 错误占位图
  loading: require('@/assets/loading.gif'), // 加载中占位图
  attempt: 3, // 重试次数
  observer: true, // 开启 IntersectionObserver
  observerOptions: {
    rootMargin: '0px 0px 200px 0px'
  }
})

组件中使用

xml 复制代码
<template>
  <img v-lazy="imageUrl" :alt="description">
</template>

二使用原生 Intersection Observer API(推荐)

原理 ‌:通过浏览器原生 API 监听图片是否进入可视区域,触发加载

优点 ‌:无依赖、性能好、支持动态内容

实现步骤‌:

  1. 注册全局自定义指令
javascript 复制代码
// main.js
Vue.directive('lazy', {
  inserted: (el, binding) => {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = new Image()
          img.src = binding.value
          img.onload = () => {
            el.src = binding.value // 加载完成后替换src
            observer.unobserve(el) // 停止观察
          }
          img.onerror = () => console.error('图片加载失败')
        }
      })
    }, { 
      rootMargin: '0px 0px 200px 0px' // 提前200px加载
    })

    observer.observe(el)
  }
})

组件中使用

xml 复制代码
<template>
  <img v-lazy="imageUrl" :alt="description">
</template>

<script>
export default {
  data() {
    return {
      imageUrl: 'https://example.com/image.jpg',
      description: '示例图片'
    }
  }
}
</script>
相关推荐
飞翔的佩奇7 分钟前
【完整源码+数据集+部署教程】【天线&水】舰船战舰检测与分类图像分割系统源码&数据集全套:改进yolo11-repvit
前端·python·yolo·计算机视觉·数据集·yolo11·舰船战舰检测与分类图像分割系统
哆啦A梦15881 小时前
点击Top切换数据
前端·javascript·vue.js
程序猿追1 小时前
Vue组件化开发
前端·html
艾德金的溪2 小时前
redis-7.4.6部署安装
前端·数据库·redis·缓存
小光学长2 小时前
基于Vue的2025年哈尔滨亚冬会志愿者管理系统5zqg6m36(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
@PHARAOH2 小时前
WHAT - 受控组件和非受控组件
前端·javascript·react.js
生莫甲鲁浪戴2 小时前
Android Studio新手开发第二十六天
android·前端·android studio
JH30733 小时前
B/S架构、HTTP协议与Web服务器详解
前端·http·架构
yi碗汤园3 小时前
【超详细】C#自定义工具类-StringHelper
开发语言·前端·unity·c#·游戏引擎
怪兽20144 小时前
Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么?
android·面试