怎么配置实现代码分割?

5 阅读2分钟

代码分割(Code Splitting)的核心目标是:把一个大的 JS Bundle 拆成多个小文件,按需加载,从而减少首屏加载时间。

因为你在用 Vue3 + Vite(我记得你之前说过),所以我重点讲 Vite / Vue3 项目里的代码分割,同时顺带讲一下原理。


一、最简单的代码分割方式:import()

最常见的方法就是 动态导入(Dynamic Import)

示例

// 普通导入(不会代码分割)
import User from './User.js'

打包后会合并进主 bundle。


改成动态导入

import('./User.js').then(module => {
  const User = module.default
})

打包后:

main.js
User.xxx.js

只有执行到 import() 才会加载 User.xxx.js


二、Vue Router 自动代码分割(最常用)

Vue 项目最常见的代码分割就是 路由级别拆分

不拆分写法

import Home from '@/views/Home.vue'

const routes = [
  {
    path: '/',
    component: Home
  }
]

代码分割写法

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

打包结果:

index.js
Home.xxx.js
About.xxx.js

访问 /home 时才会下载 Home.xxx.js

这叫:

Route Level Code Splitting(路由级代码分割)


三、Vue 组件懒加载

如果某个组件很大,也可以单独拆。

示例

<script setup>
import { defineAsyncComponent } from 'vue'

const BigComponent = defineAsyncComponent(() =>
  import('./BigComponent.vue')
)
</script>

<template>
  <BigComponent />
</template>

当组件渲染时才会加载。


四、Vite 手动拆包(高级)

有时候需要 把第三方库单独打包

例如:

  • vue
  • lodash
  • echarts

可以配置:

vite.config.js

import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vue: ['vue', 'vue-router'],
          lodash: ['lodash'],
          echarts: ['echarts']
        }
      }
    }
  }
})

打包后:

index.js
vue.xxx.js
lodash.xxx.js
echarts.xxx.js

好处:

  • 浏览器缓存更稳定
  • 更新业务代码不会影响库缓存

五、常见拆包策略(面试高频)

一般拆成:

1 业务代码

index.js

2 vendor 包

vendor.js

包含:

vue
vue-router
axios

3 大型库

echarts.js
lodash.js

4 路由页面

home.js
user.js
admin.js

六、打包结果示例

原本:

bundle.js (2MB)

拆分后:

index.js (120kb)
vendor.js (300kb)
home.js (50kb)
user.js (80kb)
echarts.js (500kb)

访问首页:

index.js
vendor.js
home.js

进入图表页面:

echarts.js

七、代码分割原理(面试加分)

Webpack / Vite 的代码分割依赖 ES Module 的动态 import

import('./module.js')

构建工具会:

1️⃣ 识别 import()
2️⃣ 把模块拆成独立 chunk
3️⃣ 运行时通过 <script> 动态加载

浏览器下载:

/assets/module-abc123.js

八、再进阶一点(真正的性能优化)

实际项目会组合:

1 路由懒加载

component: () => import('@/views/Home.vue')

2 第三方库拆包

manualChunks

3 组件级懒加载

defineAsyncComponent

4 预加载

<link rel="prefetch">
<link rel="preload">

九、前端面试标准答案总结

如果面试问:

如何实现代码分割?

回答结构:

1️⃣ 使用 ES dynamic import

import()

2️⃣ 路由懒加载

component: () => import()

3️⃣ 组件懒加载

defineAsyncComponent

4️⃣ 构建工具拆包

manualChunks
splitChunks

5️⃣ 目的

  • 减少首屏加载
  • 提高缓存利用
  • 按需加载资源

如果你愿意,我可以再给你一份 前端面试最爱问的 Code Splitting 终极答案(含 Webpack + Vite + 浏览器原理) ,很多人其实答不全,我可以帮你整理一套 面试吊打面试官版本 😄