Vue性能优化:如何实现延迟加载和代码拆分?

本文介绍Vue.js应用程序的性能优化技术,包括懒加载、代码拆分和动态导入等方法,以减少捆绑包大小,提高加载速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

移动优先方法已经成为一种标准,但不确定的网络条件导致应用程序快速加载变得越来越困难。在本系列文章中,我将深入探讨我们在Storefront应用程序中所使用的Vue性能优化技术,你们也可以在自己的Vue应用程序中使用它们来实现快速加载。

Webpack捆绑的工作原理

本系列文章中的大多数技巧都与如何使JS包变得更小有关。不过,我们首先需要了解Webpack是如何捆绑文件的。

在捆绑文件时,Webpack会创建一个叫作依赖图的东西。它是一种图,链接所有导入的文件。假设Webpack配置中有一个叫作main.js的文件被指定为入口点,那么它就是依赖图的根。这个文件要导入的每个JS模块都将成为图的叶子,而这些叶子中导入的每个模块都将成为叶子的叶子。

Webpack使用这个依赖图来决定应该在输出包中包含哪些文件。输出包是一个JavaScript文件,包含了依赖图中指定的所有模块。

这个过程就像这样:

\"\"

在知道了捆绑的工作原理之后,我们就可以得出一个结论,即随着项目的增长,初始JavaScript捆绑包也会随着增大,下载和解析捆绑包所需的时间也会越长,用户等待的时间也会变长,他们离开网站的可能性也就越大。

简单地说,更大的捆绑包=更少的用户,至少在大多数情况下是这样的。

延迟加载

那么,在添加新功能和改进应用程序的同时,我们如何减小捆绑包的大小?答案很简单——延迟加载和代码拆分。

顾名思义,延迟加载就是延迟加载应用程序的部分内容。换句话说——只在真正需要它们时加载它们。代码拆分是指将应用程序拆分成可以延迟加载的块。

\"\"

在大多数情况下,你不需要在用户访问网站后立即使用JavaScript包中的所有代码。假设应用程序中有三个不同的路由,无论用户最终要访问哪个更难,总是要下载、解析和执行所有这些路由,即使他们只需要其中的一个路由。多么浪费时间和精力!

延迟加载允许我们拆分捆绑包,并只提供必要的部分,这样用户就不会浪费时间下载和解析无用的代码。

要想知道网站实际使用了多少JavaScript代码,我们可以转到devtools -\u0026gt; cmd + shift + p -\u0026gt; type coverage -\u0026gt; 单击“record”,然后应该能够看到实际使用了多少下载的代码。

\"\"

标记为红色的都是当前路由不需要的东西,可以延迟加载。如果你使用了源映射,可以单击列表中的任意一个文件,看看是哪些部分没有被调用到。可以看到,即使是vuejs.org也还有很大的改进空间。

通过延迟加载适当的组件和库,我们将Storefront的捆绑包大小减少了60%!

接下来,让我们来看看如何在Vue应用程序中使用延迟加载。

动态导入

我们可以使用Webpack动态导入来加载应用程序的某些部分。让我们看看它们的工作原理以及它们与常规导入的区别。

标准的JS模块导入:

// main.jsimport ModuleA from './module_a.js'ModuleA.doStuff()

它将作为main.js的叶子被添加到依赖图中,并被捆绑到捆绑包中。

但是,如果我们仅在某些情况下需要ModuleA呢?将这个模块与初始捆绑包捆绑在一起不是一个好主意,因为可能根本就不需要它。我们需要一种方法来告诉应用程序应该在什么时候下载这段代码。

这个时候可以使用动态导入!来看一下这个例子:

//main.jsconst getModuleA = () =\u0026gt; import('./module_a.js')// invoked as a response to some user interactiongetModuleA()  .then({ doStuff } =\u0026gt; doStuff())

我们来看看这里都发生了什么:

我们创建了一个返回import()函数的函数,而不是直接导入module_a.js。现在Webpack会将动态导入模块的内容捆绑到一个单独的文件中,除非调用了这个函数,否则import()也不会被调用,也就不会下载这个文件。在后面的代码中,我们下载了这个可选的代码块,作为对某些用户交互的响应。

通过使用动态导入,我们基本上隔离了将被添加到依赖图中的叶子(在这里是module_a),并在需要时下载它(这意味着我们也切断了在module_a.js中导入的模块)。

让我们看另一个可以更好地说明这种机制的例子。

假设我们有4个文件:main.js、module_a.js、module_b.js和module_c.js。要了解动态导入的原理,我们只需要main和module_a的源代码:

//main.jsimport ModuleB from './mobile_b.js'const getModuleA = () =\u0026gt; import('./module_a.js')getModuleA()  .then({ doStuff } =\u0026gt; doStuff())//module_a.jsimport ModuleC from './module_c.js'

通过让module_a成为一个动态导入的模块,可以让module_a及其所有子文件从依赖图中分离。当module_a被动态导入时,其中导入的所有子模块也会被加载。

换句话说,我们为依赖图创建了一个新的入口点。

\"\"

延迟加载Vue组件

我们已经知道了什么是延迟加载以及为什么需要它,现在是时候看看如何在Vue应用程序中使用它了。

好消息是它非常简单,我们可以延迟加载整个SFC以及它的css和html,语法和之前一样!

const lazyComponent = () =\u0026gt; import('Component.vue')

现在只会在请求组件时才会下载它。以下是调用Vue组件动态加载的最常用方法:

  • 调用带有import语句的函数:
const lazyComponent = () =\u0026gt; import('Component.vue')lazyComponent()
  • 请求渲染组件:
\u0026lt;template\u0026gt;  \u0026lt;div\u0026gt;     \u0026lt;lazy-component /\u0026gt;  \u0026lt;/div\u0026gt;\u0026lt;/template\u0026gt;\u0026lt;script\u0026gt;const lazyComponent = () =\u0026gt; import('Component.vue')export default {  components: { lazyComponent }}\u0026lt;/script\u0026gt;

请注意,只有当请求在模板中渲染组件时,才会调用lazyComponent函数。

例如这段代码:

\u0026lt;lazy-component v-if=\u0026quot;false\u0026quot; /\u0026gt; 

就不会动态导入组件,因为它没有被添加到DOM(但一旦值变为true就会导入,这是一种条件延迟加载Vue组件的好方法)。

应用程序增长

vue-router是一个可用于将Web应用程序拆分为单独页面的库。每个页面都变成与某个特定URL路径相关联的路由。

假设我们有一个简单的组合应用程序,具有以下结构:

\"\"

\"\"

你可能已经注意到,根据我们访问的路由的不同,可能不需要Home.vue或About.vue,但它们都在相同的app.js捆绑包中,无论用户访问哪个路由,它们都会被下载。这真是浪费下载和解析时间!

只是额外下载一个路由这并不是什么大问题,但想象一下,当这个应用程序越来越大,任何新添加的内容都意味着在首次访问时需要下载更大的捆绑包。

用户有可能在1秒钟之内就会离开我们的网站,所以这是不可接受的!

\"\"

使用vue-router进行基于路由的代码拆分

为了避免让应用程序变得更糟,我们只需要使用动态导入语法为每个路由创建单独的包。

与Vue中的其他东西一样——它非常简单。我们不需要直接将组件导入到route对象中,只需要传入一个动态导入函数。只有在解析给定的路由时,才会下载路由组件。

所以不要像这样静态导入路径组件:

import RouteComponent form './RouteComponent.vue'const routes = [{ path: /foo', component: RouteComponent }]

我们需要动态导入它,这将创建一个新的捆绑包,并将这个路由作为入口点:

const routes = [  { path: /foo', component: () =\u0026gt; import('./RouteComponent.vue') }]

使用动态导入的捆绑和路由是这个样子的:

\"\"

\"\"

Webpack将创建三个包:

  • app.js——主捆绑包,包含应用程序入口点(main.js)和每个路由所需的库或组件;

  • home.js——包含主页的捆绑包,当用户输入/路径时才会加载;

  • about.js——包含关于页面的捆绑包,当用户输入/about路径时才会加载。

这项技术几乎适用于所有应用程序,并且可以提供非常好的结果。

在很多情况下,基于路由的代码拆分将解决所有的性能问题,并且可以在几分钟内应用于几乎任何一个应用程序上!

Vue生态系统中的代码拆分

你可能正在使用Nuxt或vue-cli来创建应用程序。如果是这样,你就应该知道,它们都有一些与代码拆分有关的自定义行为:

  • 在vue-cli 3中,默认情况下将预取所有延迟加载的块。
  • 在Nuxt中,如果我们使用了Nuxt路由系统,所有页面路由默认都是经过代码拆分的。

现在让我们来看看一些常见的反模式,它会减小基于路由的代码拆分所起到的作用。

第三方捆绑反模式

第三方捆绑通常被用在单独JS文件包含node_modules模块的上下文中。

虽然把所有东西放在一个地方并缓存它们可能很诱人,但这种方法也引入了我们将所有路由捆绑在一起时遇到的问题:

\"\"

看到了问题吗?即使我们只在一个路由中使用lodash,它也会与所有其他依赖项一起被捆绑在vendor.js中,因此它总是会被加载。

将所有依赖项捆绑在一个文件中看起来很诱人,但这样会导致应用程序加载时间变长。但我们可以做得更好!

让应用程序使用基于路由的代码拆分就足以确保只下载必要的代码,只是这样会导致一些重复代码。

假设Home.vue也需要lodash。

\"\"

在这种情况下,从/about(About.vue)导航到/(Home.vue)需要下载lodash两次。

不过这仍然比下载大量的冗余代码要好,但既然已经有了同样的依赖项,就应该重用它,不是吗?

这个时候可以使用splitChunksPlugin

只需在Webpack配置中添加几行代码,就可以将公共依赖项分组到一个单独的包中,并共享它们。

// webpack.config.jsoptimization: {  splitChunks: {    chunks: 'all'  }}

我们通过chunks属性告诉Webpack应该优化哪些代码块。这里设置为all,这意味着它应该优化所有的代码。

Vuex模块的两种类型

在进一步了解如何延迟加载Vuex模块之前,你需要了解有哪些方法可用来注册Vuex模块,以及它们的优缺点。

静态Vuex模块在Store初始化期间声明。以下是显式创建静态模块的示例:

// store.jsimport { userAccountModule } from './modules/userAccount'const store = new Vuex.Store({  modules: {    user: userAccountModule  }})

上面的代码将创建一个带有静态模块userAccountModule的Vuex Store。静态模块不能取消注册,并且在Store初始化后不能更改它们的结构。

虽然这种限制对于大多数模块来说都不是问题,并且在一个地方声明所有这些限制确实有助于将所有与数据相关的内容放在一个地方,但这种方法也有一些缺点。

假设我们的应用程序中有一个带有专用Vuex模块的Admin Dashboard。

// store.jsimport { userAccountModule } from './modules/userAccount'import { adminModule } from './modules/admin'const store = new Vuex.Store({  modules: {    user: userAccountModule,     admin: adminModule  }})

你可以想象这样的模块可能非常庞大。尽管仪表盘只会被一小部分用户使用,但由于静态Vuex模块的集中注册,它的所有代码都将被包含在主捆绑包中。

\"\"

这肯定不是我们想要的结果。我们需要一种方法,只为/admin路由加载这个模块。你可能已经猜到静态模块无法满足我们的需求。所有静态模块都需要在创建Vuex Store时注册,所以不能到了后面再进行注册。

这个时候可以使用动态模块!

动态模块可以在创建Vuex Store后进行注册。这个功能意味着我们不需要在应用程序初始化时下载动态模块,并且可以将其捆绑在不同的代码块中,或者在需要时延迟加载。

首先让我们来看一下之前的代码如果使用了动态注册的admin模块将会是什么样子。

// store.jsimport { userAccountModule } from './modules/userAccount'import { adminModule } from './modules/admin'const store = new Vuex.Store({  modules: {    user: userAccountModule,   }})store.registerModule('admin', adminModule)

我们没有将adminModule对象直接传给Store的modules属性,而是使用registerModule方法在Store创建后注册它。

动态注册不需要在模块内部进行任何更改,因此可以静态或动态注册任意的Vuex模块。

Vuex模块的代码拆分

让我们回到我们的问题。既然我们知道如何动态注册admin模块,当然可以尝试将它的代码放入/admin路由捆绑包中。

让我们先暂停一下,先简要了解一下我们的应用程序。

\"\"

// router.jsimport VueRouter from 'vue-router'const Home = () =\u0026gt; import('./Home.vue')const Admin = () =\u0026gt; import('./Admin.vue')const routes = [  { path: '/', component: Home },  { path: '/admin', component: Admin }]export const router = new VueRouter({ routes }) 

在router.js中,我们有两个延迟加载并经过代码拆分的路由。admin Vuex模块仍然在主app.js捆绑包中,因为它是在store.js中静态导入的。

让我们修复这个问题,只将这个模块发送给访问/admin路由的用户,这样其他用户就不会下载冗余代码。

为此,我们将在/admin路由组件中加载admin模块,而不是在store.js中导入和注册它。

// store.jsimport { userAccountModule } from './modules/userAccount'export const store = new Vuex.Store({  modules: {    user: userAccountModule,   }})// Admin.vueimport adminModule from './admin.js'export default {   // other component logic  mounted () {     this.$store.registerModule('admin', adminModule)  },  beforeDestroy () {   this.$store.unregisterModule('admin')  }}

我们来看看都发生了什么!

我们先是在Admin.vue(/admin route)导入和注册admin Store,等到用户退出管理面板,我们就取消注册该模块,以防止同一模块被多次注册。

现在,因为admin模块是在Admin.vue(而不是store.js)中导入的,所以它将与经过代码拆分的Admnin.vue捆绑在一起!

\"\"

现在我们知道如何使用动态Vuex模块注册将特定于路由的模块分发到适当的捆绑包中。让我们来看看稍微复杂一些的场景。

延迟加载Vuex模块

假设Home.vue上有客户评价部分,我们希望显示客户对服务的积极评价。因为有很多,所以我们不想在用户进入网站后立即显示它们,而是在用户需要查看时才显示它们。我们可以添加一个“Show Testimonials”按钮,点击这个按钮后将加载并显示客户评价。

为了保存客户评价数据,我们还需要另外一个Vuex模块,我们把它叫作testimonials。这个模块将负责显示之前添加的评价和添加新的评价,但我们不需要了解实现细节。

我们希望只在用户单击了按钮后才下载testimonials模块,因为在这之前不需要它。让我们来看看如何利用动态模块注册和动态导入来实现这个功能。Testimonials.vue是Home.vue中的一个组件。

\"\"

让我们快速过一下代码。

当用户单击Show Testimonials按钮时,将调用getTestimonials()方法。它负责调用getTestimonialsModule()来获取testimonials.js。在promise完成之后(意味着模块已加载),我们就会动态注册它,并触发负责获取客户评价的动作。

testimonials.js被捆绑到一个单独的文件中,只有在调用getTestimonialsModule方法时才会下载这个文件。

\"\"

当我们退出管理面板时,只是在beforeDestroy生命周期hook中取消了之前注册的模块,如果再次进入这个路由,就不会重复加载。

参考链接:

更多内容,请关注前端之巅。

\"\"

<think>在Vue.js中,路由懒加载是一种优化技术,它可以将每个路由对应的组件分割成独立的代码块(chunk),然后当路由被访问的时候才加载对应组件的代码。这样可以显著提高应用的初始加载速度,因为初始加载时不需要下载整个应用的所有代码,而是按需加载。###实现路由懒加载的方法在VueRouter中,我们可以使用动态导入(dynamic import)语法来实现路由懒加载。动态导入利用了Webpack的代码分割功能,将每个导入的组件单独打包成一个文件。 ####基本实现在定义路由时,将组件的导入方式从静态导入改为动态导入。**静态导入(非懒加载)示例:** ```javascriptimport Homefrom '@/views/Home.vue'import Aboutfrom '@/views/About.vue'const routes= [{path:'/',component:Home },{path:'/about', component: About} ]``` **动态导入(懒加载)示例:** ```javascriptconst routes= [{path: '/',name:'Home',component:() =>import(/* webpackChunkName: "home"*/ '@/views/Home.vue')},{path: '/about',name:'About',component:() =>import(/* webpackChunkName: "about"*/ '@/views/About.vue')}] ```这里,`import()`函数返回一个Promise,Webpack会为每个动态导入的组件生成一个单独的chunk文件。`/*webpackChunkName:"home" */`是一个魔法注释,用于指定生成的chunk的名称。###魔法注释(MagicComments)使用魔法注释可以给生成的chunk指定名称,这样有助于我们管理识别这些文件。常用的魔法注释有: -`webpackChunkName`:指定chunk的名称。- `webpackPrefetch`:预取资源,表示该模块可能会在未来的一些导航中使用,浏览器会在空闲时间加载这些资源。- `webpackPreload`:预加载资源,表示该模块会在当前导航中立即使用,与父chunk并行加载。 ####预取示例```javascriptconstroutes =[{path:'/about',name:'About',component:() =>import(/* webpackChunkName: "about",webpackPrefetch: true*/ '@/views/About.vue')}] ```###路由懒加载的优势1. **减少初始加载时间**:初始加载时只加载必要的代码(如首页),其他页面在需要时再加载。2.**优化带宽使用**:用户只下载他们实际访问的页面代码。 3. **提高性能**:特别是对于大型应用,效果显著。 ###注意事项1. **代码分割点**:合理划分路由,避免分割过细导致过多的HTTP请求,也要避免分割过粗而失去懒加载的意义。 2. **预取/预加载**:合理使用预取加载可以进一步提升用户体验,但注意不要滥用,以免造成不必要的带宽消耗。3.**加载状态**:由于动态导入是异步的,在加载过程中可能需要显示一个加载状态(如加载动画),以提升用户体验。 ###完整示例下面是一个使用路由懒加载Vue Router配置示例:**src/router/index.js**```javascriptimportVue from'vue' importRouter from'vue-router'Vue.use(Router)export defaultnew Router({mode:'history',routes:[{path:'/',name: 'Home',component: ()=> import(/*webpackChunkName:"home" */'@/views/Home.vue')},{path:'/about',name:'About',component:() =>import(/* webpackChunkName: "about"*/ '@/views/About.vue')},{path: '/contact',name: 'Contact',component: ()=> import(/*webpackChunkName:"contact" */'@/views/Contact.vue')},{path:'/profile',name:'Profile',component:() =>import(/* webpackChunkName: "profile"*/ '@/views/Profile.vue'),meta: {requiresAuth: true}}] })``` ###处理加载状态在组件加载过程中,我们可以利用Vue的异步组件`<suspense>`(Vue3)或自定义加载状态(Vue2)来显示一个加载指示器。**Vue2中自定义加载状态:**```javascriptconstrouter= newRouter({routes: [{path: '/about',name: 'About',component: ()=> ({component: import(/* webpackChunkName: "about"*/ '@/views/About.vue'),loading: LoadingComponent,//加载中的组件error: ErrorComponent,//加载出错时显示的组件delay:200,//延迟显示加载组件的时间(单位:毫秒)timeout:3000//加载超时时间})}]}) ```**Vue3中使用`<suspense>`:** 在Vue3中,可以在父组件中使用`<suspense>`组件来处理异步组件的加载状态:```vue<template><router-viewv-slot="{Component }"><suspense><template#default><component:is="Component" /></template><template #fallback><div>Loading...</div></template></suspense></router-view></template> ```###总结路由懒加载Vue.js应用优化的重要手段,通过动态导入Webpack的代码分割功能,我们可以将应用拆分成多个小块,按需加载,从而提升应用的初始加载速度整体性能。结合魔法注释,我们可以更好地控制代码分割资源加载策略。 §§相关问题§§: 1.如何在Vue实现路由守卫(navigation guards)?2.Vue Router有哪几种路由模式?它们有什么区别? 3.如何实现Vue路由的嵌套路由(nested routes)?4.在VueRouter中如何处理404页面(捕获所有路由)?</think># Vue实现路由懒加载提升性能 路由懒加载Vue.js应用优化的重要技术,它可以显著提升应用的初始加载速度运行时性能。 ## 路由懒加载的原理 路由懒加载的核心思想是将路由对应的组件分割成独立的代码块(chunk),只在访问该路由时才加载对应的组件代码。这与传统的一次性加载所有组件的方式相比,具有以下优势: 1. **减少初始加载时间**:应用启动时只加载必要的核心代码 2. **优化资源利用率**:按需加载,避免下载未使用的代码 3. **提升用户体验**:加快首屏渲染速度 ## 实现路由懒加载的方法 ### 1. 使用动态导入语法 这是Vue Router官方推荐的方式,利用Webpack的代码分割功能: ```javascript // router/index.js import Vue from 'vue'; import Router from 'vue-router'; Vue.use(Router); export default new Router({ routes: [ { path: '/dashboard', name: 'Dashboard', // 使用动态导入语法 component: () => import(/* webpackChunkName: "dashboard" */ '@/views/Dashboard.vue') }, { path: '/profile', name: 'Profile', component: () => import(/* webpackChunkName: "profile" */ '@/views/Profile.vue') } ] }); ``` **解释**: - `() => import('...')` 是ES2020动态导入语法 - `/* webpackChunkName: "dashboard" */` 是Webpack的魔法注释,用于指定生成的chunk名称 ### 2. 使用Vue异步组件 Vue提供了异步组件的概念,可以结合Webpack的代码分割功能: ```javascript const Dashboard = () => ({ component: import('@/views/Dashboard.vue'), loading: LoadingComponent, // 加载中显示的组件 error: ErrorComponent, // 加载失败显示的组件 delay: 200, // 延迟显示加载组件的时间(ms) timeout: 3000 // 加载超时时间(ms) }); export default new Router({ routes: [ { path: '/dashboard', name: 'Dashboard', component: Dashboard } ] }); ``` ### 3. 使用Webpack的require.ensure 这是Webpack特有的语法,适用于旧项目: ```javascript export default new Router({ routes: [ { path: '/dashboard', name: 'Dashboard', component: resolve => require.ensure([], () => { resolve(require('@/views/Dashboard.vue')); }, 'dashboard') // 第三个参数是chunk名称 } ] }); ``` ## 路由懒加载的最佳实践 ### 1. 分组加载相关路由 将相关路由分组到同一个chunk中: ```javascript const UserRoutes = () => import(/* webpackChunkName: "user-group" */ '@/views/user'); export default new Router({ routes: [ { path: '/user/profile', component: UserRoutes, children: [ { path: '', component: () => import('@/views/user/Profile.vue') }, { path: 'settings', component: () => import('@/views/user/Settings.vue') } ] } ] }); ``` ### 2. 预加载重要路由 使用Webpack的预取指令提前加载重要路由: ```javascript { path: '/dashboard', name: 'Dashboard', component: () => import(/* webpackPrefetch: true, webpackChunkName: "dashboard" */ '@/views/Dashboard.vue') } ``` ### 3. 添加加载状态 提供良好的加载体验: ```vue <template> <div> <router-view v-slot="{ Component }"> <transition name="fade" mode="out-in"> <component :is="Component" v-if="!isLoading" /> <div v-else class="loading-container"> <spinner /> <p>加载中...</p> </div> </transition> </router-view> </div> </template> <script> export default { data() { return { isLoading: false }; }, watch: { '$route'() { this.isLoading = true; // 假设组件加载需要一定时间 setTimeout(() => { this.isLoading = false; }, 300); } } }; </script> ``` ### 4. 错误处理 处理组件加载失败的情况: ```javascript const errorHandler = (error) => { console.error('组件加载失败:', error); return import('@/views/Fallback.vue'); }; export default new Router({ routes: [ { path: '/dashboard', name: 'Dashboard', component: () => import('@/views/Dashboard.vue').catch(errorHandler) } ] }); ``` ## 性能优化对比 | 加载方式 | 初始加载时间 | 资源利用率 | 用户体验 | |----------|--------------|------------|----------| | 传统加载 | 慢 | 低 | 首屏慢,后续快 | | 懒加载 | 快 | 高 | 首屏快,切换路由时短暂等待 | ## 实际效果分析 假设一个典型的Vue应用包含以下组件: - 主应用核心:200KB - 首页:100KB - 用户中心:150KB - 设置页面:120KB - 报表页面:180KB **传统加载方式**: - 初始加载:200KB + 100KB + 150KB + 120KB + 180KB = 750KB - 加载时间:约3秒(假设网络速度250KB/s) **路由懒加载方式**: - 初始加载:200KB(核心)+ 100KB(首页)= 300KB - 加载时间:约1.2秒 - 其他页面按需加载,用户几乎感知不到延迟 ## 注意事项 1. **避免过度分割**:将太多小文件分割会导致HTTP请求过多,反而降低性能 2. **合理命名chunk**:使用webpackChunkName保持代码可维护性 3. **预加载策略**:对用户可能访问的页面使用预加载 4. **服务端渲染**:对于SEO敏感页面,考虑使用SSR而不是懒加载 ## 完整示例 ```javascript // router/index.js import Vue from 'vue'; import Router from 'vue-router'; Vue.use(Router); // 核心布局组件(非懒加载) import MainLayout from '@/layouts/MainLayout.vue'; export default new Router({ mode: 'history', routes: [ { path: '/', component: MainLayout, children: [ { path: '', name: 'Home', component: () => import(/* webpackChunkName: "home" */ '@/views/Home.vue') }, { path: 'dashboard', name: 'Dashboard', // 预加载此重要页面 component: () => import(/* webpackPrefetch: true, webpackChunkName: "dashboard" */ '@/views/Dashboard.vue') }, { path: 'profile', name: 'Profile', component: () => import(/* webpackChunkName: "user" */ '@/views/user/Profile.vue') }, { path: 'settings', name: 'Settings', component: () => import(/* webpackChunkName: "user" */ '@/views/user/Settings.vue') }, { path: 'analytics', name: 'Analytics', component: () => import(/* webpackChunkName: "reports" */ '@/views/reports/Analytics.vue') }, { path: 'reports/:id', name: 'ReportDetail', component: () => import(/* webpackChunkName: "reports" */ '@/views/reports/Detail.vue') }, { path: '*', name: 'NotFound', component: () => import(/* webpackChunkName: "error" */ '@/views/errors/NotFound.vue') } ] } ] }); ``` 路由懒加载Vue应用性能优化的关键技术,特别适合中大型应用。通过合理分割代码块、预加载关键资源提供良好的加载状态,可以显著提升用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值