跳至内容

延迟加载路由

在使用打包器构建应用程序时,JavaScript 包可能会变得相当大,从而影响页面加载时间。如果我们可以将每个路由的组件拆分为单独的块,并且只在访问路由时加载它们,这将更有效率。

Vue Router 原生支持 动态导入,这意味着您可以用动态导入替换静态导入

js
// replace
// import UserDetails from './views/UserDetails'
// with
const UserDetails = () => import('./views/UserDetails.vue')

const router = createRouter({
  // ...
  routes: [
    { path: '/users/:id', component: UserDetails }
    // or use it directly in the route definition
    { path: '/users/:id', component: () => import('./views/UserDetails.vue') },
  ],
})

component(和 components)选项接受一个函数,该函数返回一个组件的 Promise,Vue Router **只会在第一次进入页面时获取它**,然后使用缓存的版本。这意味着您也可以拥有更复杂的函数,只要它们返回一个 Promise

js
const UserDetails = () =>
  Promise.resolve({
    /* component definition */
  })

一般来说,**始终使用动态导入**来加载所有路由是一个好主意。

注意

**不要**使用 异步组件 来加载路由。异步组件仍然可以在路由组件内部使用,但路由组件本身只是动态导入。

当使用像 webpack 这样的打包器时,这将自动从 代码拆分 中获益

当使用 Babel 时,您需要添加 syntax-dynamic-import 插件,以便 Babel 可以正确解析语法。

将组件分组到同一个块中

使用 webpack

有时我们可能希望将嵌套在同一路由下的所有组件分组到同一个异步块中。为了实现这一点,我们需要使用 命名块,通过使用特殊的注释语法提供块名称(需要 webpack > 2.4)

js
const UserDetails = () =>
  import(/* webpackChunkName: "group-user" */ './UserDetails.vue')
const UserDashboard = () =>
  import(/* webpackChunkName: "group-user" */ './UserDashboard.vue')
const UserProfileEdit = () =>
  import(/* webpackChunkName: "group-user" */ './UserProfileEdit.vue')

webpack 将把具有相同块名称的任何异步模块分组到同一个异步块中。

使用 Vite

在 Vite 中,您可以在 rollupOptions 下定义块

js
// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      // https://rollup.node.org.cn/guide/en/#outputmanualchunks
      output: {
        manualChunks: {
          'group-user': [
            './src/UserDetails',
            './src/UserDashboard',
            './src/UserProfileEdit',
          ],
        },
      },
    },
  },
})