vue路由懒加载的实现方式

更新日期: 2025-10-12阅读: 30标签: 懒加载

vue项目开发中,随着功能不断增加,JavaScript文件会变得越来越大。这会导致页面首次加载时间变长,用户需要等待更久才能看到内容。路由懒加载就是解决这个问题的有效方法。


什么是路由懒加载?

路由懒加载的核心思想很简单:不一次性加载所有组件,而是当用户访问某个路由时,才去加载对应的组件。

想象一下去图书馆借书。如果没有懒加载,你需要把整个图书馆的书都搬回家。而使用懒加载,你只需要借阅当前想看的几本书。这样既节省时间,又减少负担。


为什么要使用路由懒加载?

减少初始加载时间

 - 用户不需要等待所有代码下载完成

节省带宽

 - 只加载当前页面需要的代码

提升用户体验

 - 避免长时间白屏等待

优化缓存

 - 修改单个页面时,只需要重新加载对应的代码块


方法一:使用import()动态导入

这是目前最推荐的方式,需要webpack 2.4以上版本支持。

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: () => import('./views/Home.vue')
    },
    {
      path: '/about',
      name: 'About',
      component: () => import('./views/About.vue')
    }
  ]
})

上面的写法会把所有组件打包到一个文件中。如果想要分组打包,可以使用webpack的魔法注释:

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: () => import('./views/Home.vue')
    },
    {
      path: '/about',
      name: 'About',
      component: () => import(/* webpackChunkName: "about-group" */ './views/About.vue')
    },
    {
      path: '/contact',
      name: 'Contact', 
      component: () => import(/* webpackChunkName: "about-group" */ './views/Contact.vue')
    }
  ]
})

这样About和Contact组件会被打包到同一个about-group.js文件中。


方法二:使用require.ensure()

这是webpack的传统方法,现在虽然还能用,但建议使用import()。

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: () => import('./views/Home.vue')
    },
    {
      path: '/about',
      name: 'About',
      component: (resolve) => {
        require.ensure([], () => {
          resolve(require('./views/About.vue'))
        }, 'about')
      }
    }
  ]
})

require.ensure参数说明:

  • 第一个参数:依赖模块数组
  • 第二个参数:加载完成后的回调函数
  • 第三个参数:打包后的文件名


方法三:使用Vue异步组件

这是Vue自带的异步组件加载方式:

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: () => import('./views/Home.vue')
    },
    {
      path: '/profile',
      name: 'Profile',
      component: (resolve) => require(['./views/Profile.vue'], resolve)
    }
  ]
})
需要注意的重要事项:不要混合使用静态导入和懒加载

错误的写法:

import About from './views/About.vue'  // 静态导入

const router = new Router({
  routes: [
    {
      path: '/about',
      name: 'About',
      component: () => import('./views/About.vue')  // 懒加载
    }
  ]
})

这样About组件仍然会被打包到主文件中,懒加载不会生效。

正确使用webpackChunkName

分组打包相似功能的组件:

// 用户相关页面分组
const userRoutes = [
  {
    path: '/login',
    component: () => import(/* webpackChunkName: "user" */ './views/Login.vue')
  },
  {
    path: '/register', 
    component: () => import(/* webpackChunkName: "user" */ './views/Register.vue')
  },
  {
    path: '/profile',
    component: () => import(/* webpackChunkName: "user" */ './views/Profile.vue')
  }
]

// 管理相关页面分组  
const adminRoutes = [
  {
    path: '/admin/users',
    component: () => import(/* webpackChunkName: "admin" */ './views/admin/Users.vue')
  },
  {
    path: '/admin/settings',
    component: () => import(/* webpackChunkName: "admin" */ './views/admin/Settings.vue')
  }
]


实际项目中的最佳实践

1. 按功能模块分组

const routes = [
  {
    path: '/',
    component: () => import('@/views/Home.vue')
  },
  // 商品模块
  {
    path: '/products',
    component: () => import(/* webpackChunkName: "products" */ '@/views/products/List.vue')
  },
  {
    path: '/products/:id',
    component: () => import(/* webpackChunkName: "products" */ '@/views/products/Detail.vue')
  },
  // 用户模块
  {
    path: '/user',
    component: () => import(/* webpackChunkName: "user" */ '@/views/user/Index.vue'),
    children: [
      {
        path: 'profile',
        component: () => import(/* webpackChunkName: "user" */ '@/views/user/Profile.vue')
      },
      {
        path: 'orders',
        component: () => import(/* webpackChunkName: "user" */ '@/views/user/Orders.vue')
      }
    ]
  }
]

2. 添加加载状态

懒加载组件时,网络较慢可能会出现短暂空白。可以添加加载状态:

const UserProfile = () => ({
  component: import(/* webpackChunkName: "user" */ '@/views/user/Profile.vue'),
  loading: LoadingComponent,  // 加载中显示的组件
  error: ErrorComponent,      // 加载失败显示的组件
  timeout: 10000             // 超时时间
})

3. 预加载重要页面

对于用户很可能访问的页面,可以使用webpackPrefetch:

{
  path: '/checkout',
  component: () => import(/* webpackPrefetch: true */ './views/Checkout.vue')
}


配置webpack优化打包

在vue.config.js中配置代码分割:

module.exports = {
  configureWebpack: {
    optimization: {
      splitChunks: {
        chunks: 'all',
        cacheGroups: {
          vendor: {
            name: 'chunk-vendors',
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            chunks: 'initial'
          },
          common: {
            name: 'chunk-common',
            minChunks: 2,
            priority: 5,
            chunks: 'initial'
          }
        }
      }
    }
  }
}


三种方法的比较

import()

 - 最新标准,推荐使用,支持Promise,代码简洁

require.ensure()

 - 传统方法,功能完整但语法复杂

Vue异步组件

 - Vue原生支持,适合简单的异步加载


常见问题解决

问题1:懒加载不生效

检查是否混用了静态导入,确保路由配置中全部使用动态导入。

问题2:打包文件过多

使用webpackChunkName将相关组件分组打包。

问题3:加载时间过长

考虑使用预加载或调整分割策略。

总结

路由懒加载是Vue项目性能优化的重要手段。通过合理使用import()动态导入和webpackChunkName分组,可以显著提升应用性能。

建议在新项目中使用import()方法,按功能模块组织路由分组。对于现有项目,可以逐步将静态导入改为懒加载,观察性能改善效果。

记住,优化是一个持续的过程。根据实际使用情况调整分割策略,才能达到最好的效果。

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/article/detial/12995

监听滚动条,实现数据懒加载

当滚动条滚动到底部时,加载新数据;需要根据距离底部的位置加载数据,考虑到新数据进来会使滚动条距离底部的位置有所改变,避免重复加载数据

vue懒加载

什么是懒加载?懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。在单页应用中,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多

v-lazy图片懒加载

安装插件npm install vue-lazyload --save;在main.js文件中注册插件。配置参数:preLoad提前加载高度(数字 1 表示 1 屏的高度)、error图片加载失败时显示的图片

解决el-tree lazy懒加载时,连续勾选前两个子节点后第二次进入默认选中时,将父节点也勾选的问题

在用到el-tree的懒加载和默认勾选功能时,若第一次勾选前几个连续节点,第二次进入默认勾选时,由于el-tree子节点尚未完全加载(只加载出来前几个),默认勾选已经开始

实现一个Vue自定义指令懒加载

当我们向下滚动的时候图片资源才被请求到,这也就是我们本次要实现的效果,进入页面的时候,只请求可视区域的图片资源这也就是懒加载。比如我们加载一个页面,这个页面很长很长,长到我们的浏览器可视区域装不下

前端性能优化之图片懒加载

在类电商类项目,往往存在大量的图片,如 banner 广告图,菜单导航图,美团等商家列表头图等。图片众多以及图片体积过大往往会影响页面加载速度,造成不良的用户体验,所以进行图片懒加载优化势在必行。

过度使用懒加载对 Web 性能的影响

如今为了提升应用性能,懒加载被广泛使用于 Web 应用中。它帮助开发者减少网站加载时间,节省流量以及提升用户体验。但懒加载的过度使用会给应用性能带来负面影响

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!