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

组件懒加载

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

  1. ‌Vue Router 动态导入 ‌

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

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

‌React Router v6+ 方案 ‌

结合 React.lazy 和 Suspense 实现按需加载‌:

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>
相关推荐
鬼手点金几秒前
opencode-隐私优先配置
服务器·前端·javascript·bug·openclaw
且从容.1 分钟前
JS篇-----
java·javascript·jvm
涛涛ing4 分钟前
4200万月活、85万行代码,Lovable用6个月把生产应用从Next.js迁到了TanStack Start
前端
悠仁さん7 分钟前
【C++】auto
java·前端·c++
吠品31 分钟前
箭头函数为什么不能 new
开发语言·javascript·原型模式
liangshanbo121534 分钟前
面试题:React.memo 和 useMemo 的区别
前端·react.js·前端框架
苹果二36 分钟前
使用Vue的指南
前端·javascript·vue.js
害人终害己1 小时前
‘vue-cli-service‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。
前端·javascript·vue.js
被摘下的星星1 小时前
CSS 基础说明
前端·css
怕浪猫10 小时前
RAG 面试 6 连问,从原理到优化全部覆盖
python·算法·面试