反应路由器基本代码拆分(获取第一个块,然后在后台异步获取其他块)
Posted
技术标签:
【中文标题】反应路由器基本代码拆分(获取第一个块,然后在后台异步获取其他块)【英文标题】:React router base code-splitting (get first chunk and then get other chunks async in background) 【发布时间】:2020-09-07 21:25:51 【问题描述】:我正在使用create-react-app。我想反应路由器基本代码拆分,但我想获取用户在浏览器中打开的第一个块,然后在后台异步获取其他块
路线
const HomeModule = React.lazy(() => import('./modules/ft_home_module/src/main'));
const AuthModule = React.lazy(() => import('./modules/ft_auth_module/src/main'));
const ProfileModule = React.lazy(() => import('./modules/ft_profile_module/src/main'));
const MerchantModule = React.lazy(() => import('./modules/ft_merchant_module/src/main'));
<Route path="/home" component=HomeModule />
<Route path="/auth" component=AuthModule />
<Route path="/profile" component=ProfileModule />
<Route path="/merchant" component=MerchantModule />
假设,如果用户在浏览器中打开/home,那么在加载第一个块后,将首先加载主块,在后台异步调用其他块
所需输出
-
在浏览器中打开
/home
先获取 home 块
然后其他三个块在后台异步进行
实际上我正在通过lighthouse chrome extension 测试性能。路由器基本代码拆分为我提供了第一页的良好性能,但是当我打开第二页时,它需要时间,但它不应该花费时间。我认为如果我们在加载第一个块后让其他块在后台异步是可能的
【问题讨论】:
【参考方案1】:您可以通过使用浏览器资源提示(预加载和预取)来实现这一点
如果你使用 webpack,那么魔法 cmets 会很有帮助。你可以试试这样的:
const HomeModule = React.lazy(() => import(/* webpackPreload: true * /'./modules/ft_home_module/src/main'));
const AuthModule = React.lazy(() => import(/* webpackPrefetch: true * /'./modules/ft_auth_module/src/main'));
const ProfileModule = React.lazy(() => import(/* webpackPrefetch: true * /'./modules/ft_profile_module/src/main'));
const MerchantModule = React.lazy(() => import(/* webpackPrefetch: true */ './modules/ft_merchant_module/src/main'));
在上述情况下,无论url是什么,它都会预加载homemodule并预取其他三个低优先级的模块。
如果你想要动态行为,你可以尝试使用插件: https://github.com/SebastianS90/webpack-prefetch-chunk
添加插件后,您可以使用 webpack_require.pfc 方法在后台加载块。
const prefetchChunk = chunkName =>
if (!window.requestIdleCallback)
return;
else if (chunkName)
let chunkArray = [].concat(chunkName);
window.requestIdleCallback(() =>
chunkArray.forEach(chunk =>
__webpack_require__.pfc(chunk);
);
);
else
return;
;
【讨论】:
我知道,但我想在用户从浏览器调用时加载第一个块,然后在后台异步调用其他块 Prefetch 选项将通知浏览器在空闲时间下载块。如果您想更好地控制需要预取哪些块,您应该将提到的插件添加到 webpack 配置中。 我正在使用创建反应应用程序。它可以用于创建反应应用程序吗? 大部分是的。我没有尝试过创建反应应用程序。第一个选项可以正常工作。如果你要使用插件,那么你需要在 create react 应用程序中包含这个插件。这可能会有所帮助:dev.to/nodewarrior/…【参考方案2】:用 Suspense 包裹路由器,该路由器采用回退(在加载块时显示一些内容,如果尚未加载)...
import React,Suspense from 'react';
import Router from '@reach/router';
const HomeModule = React.lazy(() => import('./modules/ft_home_module/src/main'));
const AuthModule = React.lazy(() => import('./modules/ft_auth_module/src/main'))
const ProfileModule = React.lazy(() => import('./modules/ft_profile_module/src/main'));
const MerchantModule = React.lazy(() => import('./modules/ft_merchant_module/src/main'));
const Loading = () => <div>Loading chunk..</div>;
return (
<Suspense fallback=<Loading/>>
<Router>
<HomeModule path="/home" />
<AuthModule path="/auth" />
<ProfileModule path="/profile" />
<MerchantModule path="/merchant" />
</Router>
</Suspense>
)
【讨论】:
我已经在使用它,但它没有按要求工作,请准备好我的问题以上是关于反应路由器基本代码拆分(获取第一个块,然后在后台异步获取其他块)的主要内容,如果未能解决你的问题,请参考以下文章