提升SPA路由切换速度的关键是减少“加载—解析—执行—挂载”链路重复开销,需通过按需加载+内容哈希、组件缓存与状态保留、接口数据预取及精准modulepreload实现。

提升单页应用(SPA)内部路由切换速度,关键不是让 JS 下载更快,而是减少“加载—解析—执行—挂载”整条链路上的重复开销。重点在资源分层控制、状态复用和生命周期干预,而非堆砌预加载指令。
按需加载 + 内容哈希:切掉冗余代码
把每个路由对应组件拆成独立 chunk,构建时生成带内容哈希的文件名(如 profile.a2f8c1.js),服务端对这类资源返回 Cache-Control: public, max-age=31536000。这样:
- 用户首次访问 /profile 才下载 profile.a2f8c1.js,其他路由不占带宽
- 公共依赖(React、工具函数等)抽成单独 vendor.e9d4b2.js,多个路由共用一份缓存
- JS 文件内容一变,哈希就变,URL 就变 → 浏览器自动忽略旧缓存,无需手动清缓存
避免重渲染:组件缓存与状态保留
路由切换时,反复销毁再创建组件是性能黑洞。可用以下方式保留实例和输入状态:
- Vue 中用 <keep-alive> 包裹路由出口,已访问过的页面 DOM 和组件实例保留在内存中
- React 中用 React Router 的 unstable_useBlocker 或自定义 Hook 拦截跳转,结合 sessionStorage 持久化表单字段
- 多步流程(如注册页)改用 hash 或 query 参数切换视图,不触发完整路由跳转
接口数据预取:比预加载 JS 更有效
用户点「下一步」前,提前 fetch 下一页需要的数据,而不是预取 JS 文件:
立即学习“Java免费学习笔记(深入)”;
- 鼠标悬停「提交」按钮时,发起 fetch('/api/submit-check')
- 路由进入前(如 beforeEach 钩子),检查 localStorage 中是否有未过期的菜单数据,有则直接渲染,同时后台静默更新
- 敏感数据(如余额、订单状态)跳过缓存,或 fetch 时显式加 cache: 'no-store'
首屏资源精准预加载:只用 modulepreload
prefetch 对 SPA 路由切换基本无效——它只存文件不执行,且常被中止。真正起作用的是:
- 在 HTML 中 首个 type="module" 脚本之前 放:
<link rel="modulepreload" href="/assets/app.8e3d2a.js"> - href 必须和 import('./app.js') 或 <script type="module" src="..."> 中路径完全一致(含查询参数)
- 服务端返回 MIME 类型必须是 application/javascript,否则部分浏览器拒绝执行



















