为什么 用vite进行分包后,可以通过 浏览器强制缓存 提高性能?路由懒加载进行的分包与 vite进行的分包有什么不同?

发布时间:2026/5/21 7:29:11

为什么 用vite进行分包后,可以通过 浏览器强制缓存 提高性能?路由懒加载进行的分包与 vite进行的分包有什么不同? 文章目录一、为什么 用vite进行分包后可以通过浏览器强制缓存提高性能1、 什么是浏览器强制缓存1.1 协商缓存需要举手提问 ‍♂️1.2 强制缓存霸道总裁直接拿来用 ⚡2、 强缓存这么好那它有什么致命缺点3、 为什么用 Vite 分包后能通过强缓存大幅提高性能场景 A不分包所有的东西揉成一个 index-[hash].js场景 B用 Vite 分包利用 manualChunks 拆分二、路由懒加载进行的分包与 vite进行的分包有什么不同1. 什么是路由懒加载如果不用懒加载全量打包用了懒加载2. 什么是 Vite/Rollup 的 manualChunks 分包为什么需要它3. 两者有什么不同核心对比4. 它们是如何协同工作的1 1 绝对大于 2完美的加载流程一、为什么 用vite进行分包后可以通过浏览器强制缓存提高性能要想完全理解为什么 Vite 分包能利用强制缓存大幅提升性能我们得先拆开来看先明白浏览器缓存的“游戏规则”再看 Vite 是怎么利用这个规则在生产环境“作弊”的。1、 什么是浏览器强制缓存浏览器缓存分为两种协商缓存和强制缓存。它们的区别就在于要不要去问服务器。1.1 协商缓存需要举手提问 ‍♂️浏览器每次用这个文件前都要发个请求问服务器“服务器大哥我本地有这个文件它过期了吗” 服务器对比一下如果没变返回一个304 Not Modified浏览器再读取本地缓存。缺点虽然传输体积变小了但依然发出了一次 HTTP 网络请求。只要有网络请求就会受到网络延迟RTT的限制。1.2 强制缓存霸道总裁直接拿来用 ⚡服务器在第一次返回文件时在响应头Response Headers里加上一个标记比如Cache-Control: max-age31536000告诉浏览器这文件一年内都不会变。当用户第二次访问或者刷新页面时浏览器一看这个标记“哦还在保质期内呢我连网络请求都不发了直接从本地内存Memory Cache或硬盘Disk Cache里把文件秒秒钟拿出来。”状态码在开发者工具的 Network 面板里你会看到状态码是200 OK (from disk cache)。收益网络请求数直接变成0耗时接近0ms。这是最极致的网络性能优化。2、 强缓存这么好那它有什么致命缺点强缓存唯一的缺点就是太死板。如果服务器上的代码更新了但是浏览器以为文件还在“保质期”内它就绝对不会向服务器发请求而是继续使用本地的老代码。这就导致了用户打不开新功能、或者页面直接报错俗称“发版后缓存不更新”。现代前端Vite/Webpack解决这个问题的终极武器就是内容哈希Content Hash。当 Vite 打包时会根据文件的内容计算出一个唯一的哈希值作为文件名比如index-b87a2c.js。只要你改了代码打包出来的文件名就会变成index-f49e1a.js。因为 HTML 页面是绝对不走强缓存的HTML 通常配置Cache-Control: no-cache浏览器每次都会拉取最新的 HTML。最新的 HTML 里引用了新的 JS 文件名浏览器就会去下载新文件而没变的文件名浏览器继续走强缓存。3、 为什么用 Vite 分包后能通过强缓存大幅提高性能这就聊到你问的核心了。如果不分包强缓存的威力会被严重削弱。场景 A不分包所有的东西揉成一个index-[hash].js你把 Vue 核心库、Pinia、Axios、Echarts 还有你写的几百个业务组件全部打进了一个巨大的index-v1.js里。这个包很大比如 2MB你给它设置了强缓存。问题来了第二天你发现首页有个错别字你把“欢荧光临”改成了“欢迎光临”。打包结果由于内容变了整个 2MB 的大包文件名瞬间变成了index-v2.js。用户代价用户重新访问时浏览器发现文件名变了强缓存全部失效。用户不得不为了你改动的一个错别字把原本完全没变的 Vue、Echarts 等第三方大库重新下载了一遍用户的首屏加载又变慢了。场景 B用 Vite 分包利用manualChunks拆分你通过 Vite 配置把包拆开了dist/assets/ ├── vendor-d7c3a1.js# 包含 vue, vue-router, pinia, axios (150kb)├── echarts-8f4e2a.js# 包含完整的 echarts 图表库 (500kb)└── index-b87a2c.js# 纯粹是你自己写的业务代码 (50kb)这时候你同样给assets目录下的所有 JS 文件在服务器如 Nginx上配置了强制缓存。同样是改了一个首页错别字你再次打包vendor里的代码没变打包出来依然叫vendor-d7c3a1.js。echarts里的代码没变打包出来依然叫echarts-8f4e2a.js。你的业务代码变了打包出来变成了index-f49e1a.js。此时用户重新进站神奇的事情发生了浏览器请求最新的 HTML发现里面引用了这三个文件。vendor-d7c3a1.js匹配本地缓存 ➡️命中强缓存0ms 搞定echarts-8f4e2a.js匹配本地缓存 ➡️命中强缓存0ms 搞定index-f49e1a.js找不到发请求下载 ➡️只下载了 50kb 的核心业务包。最终结论Vite 分包的本质是把“轻易不会变动的重型资产第三方库”与“天天都在变动的轻量资产业务代码”在物理上隔离开。这样就能保证那些体积最大、下载最慢的第三方库可以在用户本地的浏览器里永久命中强缓存只有真正更新了的业务小包才走网络下载。首屏速度自然迎来了质的飞跃。二、路由懒加载进行的分包与 vite进行的分包有什么不同路由懒加载和rollupOptions.manualChunks配置分包虽然最终结果都是“把代码拆成了多个 JS 小包”但它们的触发时机、控制维度和核心目的截然不同。我们可以把它们比作“业务层面的按需索取”与“物理层面的资产归类”。1. 什么是路由懒加载简单来说路由懒加载是业务逻辑驱动的代码拆分Code Splitting。如果不用懒加载全量打包当你访问项目的登录页http://localhost/login时浏览器会把主页、个人中心、后台数据大屏等所有页面的 JS 代码一次性全部下载下来。结果首屏巨慢用户明明只看了一个登录页却要为整个系统的代码买单。用了懒加载constDashboard()import(./views/Dashboard.vue)当打包工具Vite/Rollup看到import()这种动态导入语法时它会敏锐地意识到“哦这个组件不需要一上来就加载。那我单独把它切出来打包成一个独立的dashboard-[hash].js文件吧。”什么时候下载只有当用户真正点击了“控制台”路由引发路由跳转时浏览器才会通过网络去请求下载这个dashboard-[hash].js。2. 什么是 Vite/Rollup 的 manualChunks 分包配置分包如manualChunks是物理/依赖层面驱动的包体积合并与归类。它是纯粹的工程化手段不管你业务怎么跳转它只关心的文件依赖关系和缓存命中率。为什么需要它如果你只配置了路由懒加载那么每个路由页面里引用的第三方库比如lodash、echarts等可能就会被散落打包到各个路由小包里或者有些公用组件被重复打包。通过manualChunks你可以硬性规定manualChunks(id){if(id.includes(node_modules)){// 把所有来自 node_modules 的第三方依赖单独打包成一个叫 vendor 的大包returnvendor;}}结果把业务代码和第三方生态彻底剥离。因为node_modules里的依赖基本不会变这样打包出来的vendor.js就可以完美触发浏览器的强缓存304 或 Cache-Control。即使你天天改业务代码发布新版本用户也只需要重新下载小巧的业务包vendor.js直接走本地缓存速度飞快。3. 两者有什么不同核心对比为了更直观我们通过一张表来看看它们在编译和运行时的本质区别维度路由懒加载动态导入import()Vite/Rollup 配置分包 (manualChunks)决定权在谁开发者业务层由你的路由代码怎么写决定。打包工具构建层由你的打包配置文件决定。主要目的减少首屏加载体积不下载当前不需要的页面。优化浏览器缓存把变动频繁的业务码和稳定的第三方库分开。工作阶段**运行时Runtime**按需异步加载。**构建时Build time**做物理文件分类。典型代表() import(./Detail.vue)将axios、vue统一打包进vendor.js。4. 它们是如何协同工作的1 1 绝对大于 2在实际的 Vite 项目中我们不是二选一而是两者结合使用。设想一个标准的 Vue Vite 项目打包后的文件结构dist/assets/ ├── index-AX432j.js# 主包包含 Vue 核心、main.js、全局状态首屏必须├── vendor-BC892k.js# 由 manualChunks 拆出来的第三方库大包走强缓存首屏必须├── Home-CD123f.js# 路由懒加载拆出的首页首屏必须├── About-EF456g.js# 路由懒加载拆出的关于页用户点到 About 时才下载└── Dashboard-GH789h.js# 路由懒加载拆出的后台页用户点到 Dashboard 时才下载完美的加载流程用户首次访问首页。浏览器只下载了index.js、vendor.js、和首屏对应的Home.js。页面瞬间加载完成首屏速度优化成功 ⚡。用户点击进入“关于我们”页面浏览器默默发了一个网络请求拉取了About.js路由懒加载生效 ⚡。第二天你修改了首页的一个文案重新打包发布。用户再次访问浏览器发现vendor.js没变直接读取本地缓存只下载了变动的一点点业务包manualChunks缓存优化成功 ⚡。

相关新闻