07 · 性能优化与预取策略
Fetch 三层装饰(组合顺序)
loadApp 中的组合为:
typescript
makeFetchCacheable(makeFetchRetryable(makeFetchThrowable(fetch)))1. makeFetchThrowable
非成功 HTTP 状态会抛错,便于上层统一错误处理,而不是静默得到「空 body + 200 以外」的难调试状态(实现见 packages/shared/src/fetch-utils/makeFetchThrowable.ts)。
2. makeFetchRetryable
对失败请求做重试,减轻弱网抖动对入口/脚本加载的影响(makeFetchRetryable.ts)。
3. makeFetchCacheable:全局 LRU + clone()
- 使用 全局
LRUCache(once单例),容量 50(makeFetchCacheable.ts)。 - 命中缓存时
res.clone(),注释强调:同一 Response body 只能读一次,流式场景尤其如此。
33:34:packages/shared/src/fetch-utils/makeFetchCacheable.ts
// must clone the response as one response body can only be read once as a stream
return res.clone();失败或非 2xx 会从缓存剔除,避免脏缓存长期存在。
流式解析期间的 preload
见 03-流式Loader与Head虚拟化.md:在同步脚本 / stylesheet 阻塞解析时,writable-dom 会向前扫描并插入 link rel=preload,把后续资源拉取并行化。
fetchPriority
同步脚本在转译完成后设置 script.fetchPriority = 'high',让浏览器优先调度执行(script.ts 中注释说明)。
prefetchApps(v3 已标记废弃)
prefetchApps 在开发环境会 console.warn,说明 3.0 中由 streaming loader 自动 preload,旧的手动 prefetch API 退居二线:
109:118:packages/qiankun/src/apis/prefetch.ts
/**
* Prefetch micro apps immediately
* @deprecated This API is deprecated in qiankun 3.0. Micro apps are streamed with automatic preload now.
* @param apps - Apps to prefetch
* @param fetch - Custom fetch function
*/
export function prefetchApps(apps: AppMetadata[], fetch: typeof window.fetch = window.fetch): void {
if (process.env.NODE_ENV === 'development') {
// eslint-disable-next-line no-console
console.warn('[qiankun] prefetchApps is deprecated in 3.0; streaming loader performs automatic preload.');旧实现仍体现产品思路:requestIdleCallback 分片、navigator.connection 判断慢网/省流量时不预取,避免抢带宽(同文件 prefetch 函数前部)。
开发环境 Performance API
loadApp 在 development 对单次加载打 performance.mark / measure,用于本地分析加载耗时(loadApp.ts 55-57、158-163 行)。
依赖复用(间接优化)
moduleResolver 命中主应用已加载依赖时,减少重复下载与重复初始化(见 05-资源转译与依赖共享.md)。