news 2026/6/23 1:20:27

路由懒加载

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
路由懒加载

文章目录

  • 前言
  • 一、基本原理
    • 1.1 动态 import 拆分 chunk
    • 1.2 与同步引入对比
  • 二、Webpack 魔法注释
    • 2.1 自定义 chunk 名称
    • 2.2 prefetch:空闲时预加载
    • 2.3 preload:并行高优先级加载
    • 2.4 prefetch vs preload
  • 三、Vite 批量注册路由
    • 3.1 import.meta.glob
    • 3.2 按模块分组
  • 四、defineAsyncComponent 与路由懒加载
    • 4.1 区别
  • 五、典型场景
    • 5.1 中后台按业务模块懒加载
    • 5.2 权限路由动态加载
    • 5.3 首屏同步 + 其余懒加载
  • 六、面试聚焦
    • 6.1 prefetch 与 preload 区别
    • 6.2 懒加载的组件会重复请求吗?
    • 6.3 路由懒加载 vs defineAsyncComponent
  • 七、易混淆点
  • 八、思考与练习
  • 总结

前言

路由懒加载是 Vue SPA 首屏优化的常用手段,通过动态import()将页面组件拆成独立 chunk,访问时才加载。本篇会讲清楚:

  • 路由懒加载的原理与写法
  • Vite 批量注册与 prefetch / preload 区别
  • defineAsyncComponent 与路由懒加载的场景区别

一、基本原理

1.1 动态 import 拆分 chunk

constroutes=[{path:'/',component:()=>import('@/views/Home.vue')// 懒加载},{path:'/user',component:()=>import('@/views/User.vue')},{path:'/order',component:()=>import('@/views/Order.vue')}]

工作流程

  1. 构建工具(Webpack / Vite)为每个动态import()生成独立 chunk 文件(带 content hash)
  2. 首屏只加载当前路由所需代码,其余 chunk 不下载
  3. 用户导航到对应路由时,浏览器再请求该 chunk
  4. chunk 下载完成后渲染页面组件

1.2 与同步引入对比

// ❌ 同步引入:所有页面打包进主 bundle,首屏体积大importHomefrom'@/views/Home.vue'importUserfrom'@/views/User.vue'importOrderfrom'@/views/Order.vue'// ✅ 懒加载:按路由拆分,首屏只加载 Homecomponent:()=>import('@/views/User.vue')
对比项同步引入路由懒加载
首屏体积大(全部页面)小(当前页面)
加载时机应用启动时导航到该路由时
适用场景首屏必需页面非首屏业务页面

二、Webpack 魔法注释

2.1 自定义 chunk 名称

constroutes=[{path:'/order',component:()=>import(/* webpackChunkName: "order" */'@/views/Order.vue')}]// 生成文件:order.[hash].js(便于调试和缓存分析)

2.2 prefetch:空闲时预加载

{path:'/dashboard',component:()=>import(/* webpackPrefetch: true */'@/views/Dashboard.vue')}

浏览器在空闲时提前下载该 chunk,用户后续导航时可更快渲染。适合「很可能接下来会访问」的页面。

2.3 preload:并行高优先级加载

{path:'/critical',component:()=>import(/* webpackPreload: true */'@/views/Critical.vue')}

与父 chunk并行加载,优先级高。适合当前页面很快就要用到的模块。

2.4 prefetch vs preload

对比项preloadprefetch
加载时机与父 chunk 并行浏览器空闲时
优先级
用途当前页面即将需要未来可能访问
典型场景首屏关键子模块其他路由页面
<!-- preload --><linkrel="preload"href="critical.js"as="script"><!-- prefetch --><linkrel="prefetch"href="dashboard.js"as="script">

Vite 生产构建同样支持这些 magic comment,行为与 Webpack 类似。


三、Vite 批量注册路由

3.1 import.meta.glob

页面较多时,可批量扫描并自动生成懒加载路由:

// router/routes.jsconstmodules=import.meta.glob('../views/**/*.vue')constroutes=Object.entries(modules).map(([path,component])=>{// '../views/user/List.vue' → '/user/list'constroutePath=path.replace('../views','').replace(/\.vue$/,'').replace(/\/index$/,'').toLowerCase()return{path:routePath||'/',component// 已是 () => import() 形式}})

3.2 按模块分组

// 只扫描 admin 目录constadminModules=import.meta.glob('../views/admin/**/*.vue')// eager: true 则同步加载(非懒加载)constsyncModules=import.meta.glob('./dir/*.js',{eager:true})

适合中后台系统大量页面模块的自动注册,减少手动维护 routes 数组。


四、defineAsyncComponent 与路由懒加载

4.1 区别

// 路由懒加载:Vue Router 直接使用动态 import{path:'/user',component:()=>import('@/views/User.vue')}// defineAsyncComponent:用于非路由场景的异步组件import{defineAsyncComponent}from'vue'constAsyncChart=defineAsyncComponent({loader:()=>import('@/components/Chart.vue'),loadingComponent:LoadingSpinner,errorComponent:ErrorDisplay,delay:200,timeout:10000})
对比项路由懒加载defineAsyncComponent
使用场景路由页面组件弹窗、Tab、动态组件
加载配置NProgress / 全局 loadingloading / error / timeout
代码分割按路由拆 chunk按组件拆 chunk

路由场景直接用() => import()即可;需要 loading/error 降级时用defineAsyncComponent包装后再作为 component。


五、典型场景

5.1 中后台按业务模块懒加载

constroutes=[{path:'/user',component:()=>import('@/views/user/index.vue')},{path:'/order',component:()=>import('@/views/order/index.vue')},{path:'/report',component:()=>import('@/views/report/index.vue')}]

5.2 权限路由动态加载

// 根据角色动态 addRoute,模块本身也是懒加载constadminRoutes=[{path:'/admin',component:()=>import('@/layouts/AdminLayout.vue'),children:[{path:'users',component:()=>import('@/views/admin/Users.vue')}]}]if(role==='admin'){adminRoutes.forEach(route=>router.addRoute(route))}

5.3 首屏同步 + 其余懒加载

importHomefrom'@/views/Home.vue'// 首屏同步加载constroutes=[{path:'/',component:Home},{path:'/about',component:()=>import('@/views/About.vue')},{path:'/contact',component:()=>import('@/views/Contact.vue')}]

首屏关键页面同步引入,其余全部懒加载,平衡 FCP 与总体积。


六、面试聚焦

6.1 prefetch 与 preload 区别

  • preload:高优先级,与父 chunk 并行,当前页面很快需要
  • prefetch:低优先级,浏览器空闲时加载,未来可能访问的路由

6.2 懒加载的组件会重复请求吗?

不会(正常情况下)。首次访问后 chunk 被浏览器缓存,后续导航直接使用缓存。只有构建后文件 hash 变化(发版更新)才会重新请求。

6.3 路由懒加载 vs defineAsyncComponent

路由懒加载用于页面级代码分割;defineAsyncComponent用于组件级异步加载,可配置 loading/error 状态,两者场景不同。


七、易混淆点

  1. 懒加载 ≠ 不加载:首次进入该路由仍会请求 chunk,只是不在首屏加载。
  2. chunk 会缓存:除非 hash 变化,否则不会重复下载。
  3. defineAsyncComponent 不替代路由懒加载:路由直接用() => import()更简洁。
  4. import.meta.glob 默认懒加载:不加eager: true时返回的都是动态 import 函数。
  5. prefetch 不是立即加载:在浏览器空闲时才预取,不要与 preload 混用场景。

八、思考与练习

1.路由懒加载的原理是什么?

解析:路由 component 使用动态import(),构建工具拆成独立 chunk;导航到该路由时才下载并执行,减小首屏 bundle。

2.prefetch 和 preload 如何选择?

解析:preload 用于当前页面即将需要的模块(高优先级并行);prefetch 用于其他路由页面,空闲时预取。

3.懒加载后第二次访问还会请求吗?

解析:不会重复请求,浏览器已缓存该 chunk;发版后 hash 变化才会重新下载。

4.如何给路由切换加 Loading 效果?

解析:常用 NProgress 配合路由守卫(beforeEach 开始、afterEach 结束),或使用defineAsyncComponentloadingComponent配置加载态组件。

5.Vite 如何批量注册懒加载路由?

constmodules=import.meta.glob('../views/**/*.vue')// 遍历 modules 生成 routes 数组

总结

  • 原理:动态import()按路由拆分 chunk,访问时才加载,减小首屏体积
  • 魔法注释webpackChunkName命名、webpackPrefetch空闲预取、webpackPreload并行加载
  • import.meta.glob:Vite 批量扫描页面,自动生成懒加载路由
  • 选型:路由用() => import();非路由异步组件用defineAsyncComponent
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 0:52:47

智能语音交互的声学革新:从降噪到体验的全方位突破

在智能语音设备的开发浪潮中&#xff0c;声学技术正成为决定产品体验的关键因素。用户对语音交互的期待不断提升&#xff1a;从嘈杂环境中的精准唤醒&#xff0c;到无回声干扰的自然通话&#xff0c;再到设备小型化与性能的平衡&#xff0c;工程师们面临着多重技术挑战。本文将…

作者头像 李华
网站建设 2026/6/23 0:50:33

Sunshine自托管游戏串流:打造低延迟跨平台游戏共享解决方案

Sunshine自托管游戏串流&#xff1a;打造低延迟跨平台游戏共享解决方案 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否厌倦了被云游戏平台束缚&#xff0c;渴望在任何设备上…

作者头像 李华
网站建设 2026/6/23 0:44:32

嵌入式调试器命令实战:从自动化脚本到高效问题定位

1. 调试器命令&#xff1a;嵌入式开发的“手术刀”在嵌入式开发的世界里&#xff0c;调试器远不止是一个“找Bug”的工具&#xff0c;它更像是一把精密的手术刀&#xff0c;让我们能够深入微控制器的“大脑”&#xff0c;实时观察其思维过程&#xff0c;甚至进行干预。而调试器…

作者头像 李华
网站建设 2026/6/23 0:42:43

SAMA5D3低功耗设计实战:从硬件到Linux系统的全方位优化指南

1. 项目缘起&#xff1a;为什么SAMA5D3的低功耗设计是个“技术活”&#xff1f;几年前&#xff0c;我接手一个户外环境监测终端的项目&#xff0c;主控选型时看中了Atmel&#xff08;现在归Microchip&#xff09;的SAMA5D3系列。这芯片名气不小&#xff0c;基于ARM Cortex-A5内…

作者头像 李华