diff --git a/docs/docs/docs/api/api.en-US.md b/docs/docs/docs/api/api.en-US.md index 5c7432892927..b3b99b46e91b 100644 --- a/docs/docs/docs/api/api.en-US.md +++ b/docs/docs/docs/api/api.en-US.md @@ -207,7 +207,7 @@ function IndexPage({ user }) { `` supports relative path navigation; `` does not do routing navigation and is equivalent to the jump behavior of ``. -If `prefetch` is enabled, then when the user hovers over the component, Umi will automatically start preloading the component js files and data for the routing jump. +If `prefetch` is enabled, then when the user hovers over the component, Umi will automatically start preloading the component js files and data for the routing jump. (Note: Use this feature when `routePrefetch` and `manifest` are enabled) ### matchPath diff --git a/docs/docs/docs/api/api.md b/docs/docs/docs/api/api.md index a43c0c3f9548..4139c76bbb32 100644 --- a/docs/docs/docs/api/api.md +++ b/docs/docs/docs/api/api.md @@ -206,7 +206,7 @@ function IndexPage({ user }) { `` 支持相对路径跳转;`` 不做路由跳转,等同于 `` 的跳转行为。 -若开启了 `prefetch` 则当用户将鼠标放到该组件上方时,Umi 就会自动开始进行跳转路由的组件 js 文件和数据预加载。 +若开启了 `prefetch` 则当用户将鼠标放到该组件上方时,Umi 就会自动开始进行跳转路由的组件 js 文件和数据预加载。(注:使用此功能请同时开启 `routePrefetch` 和 `manifest` 配置) ### matchPath diff --git a/packages/renderer-react/src/browser.tsx b/packages/renderer-react/src/browser.tsx index 116d60d1b2be..ca8c7d0f7347 100644 --- a/packages/renderer-react/src/browser.tsx +++ b/packages/renderer-react/src/browser.tsx @@ -249,42 +249,17 @@ const getBrowser = ( ) || [] ).filter(Boolean); matchedRouteIds.forEach((id) => { - // preload - // @ts-ignore - const manifest = window.__umi_manifest__; - if (manifest) { - const routeIdReplaced = id.replace(/[\/\-]/g, '_'); - const preloadId = `preload-${routeIdReplaced}.js`; - if (!document.getElementById(preloadId)) { - const keys = Object.keys(manifest).filter((k) => - k.startsWith(routeIdReplaced + '.'), - ); - keys.forEach((key) => { - if (!/\.(js|css)$/.test(key)) { - throw Error(`preload not support ${key} file`); - } - let file = manifest[key]; - const link = document.createElement('link'); - link.rel = 'preload'; - link.as = 'style'; - if (key.endsWith('.js')) { - link.as = 'script'; - link.id = preloadId; - } - // publicPath already in the manifest, - // but if runtimePublicPath is true, we need to replace it - if (opts.runtimePublicPath) { - file = file.replace( - new RegExp(`^${opts.publicPath}`), - // @ts-ignore - window.publicPath, - ); - } - link.href = file; - document.head.appendChild(link); - }); + // preload lazy component + // window.__umi_manifest__ is available when routePrefetch and manifest config is enabled + // __umi_manifest__ is not needed for preload, keep this is for compatibility and minimal change + if ((window as any).__umi_manifest__) { + // ref: https://github.com/facebook/react/blob/0940414/packages/react/src/ReactLazy.js#L135 + const lazyCtor = opts.routeComponents[id]?._payload?._result; + if (typeof lazyCtor == 'function') { + lazyCtor(); } } + const clientLoader = opts.routes[id]?.clientLoader; const hasClientLoader = !!clientLoader; const hasServerLoader = opts.routes[id]?.hasServerLoader;