反应路由器基本代码拆分(获取第一个块,然后在后台异步获取其他块)

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>
)

【讨论】:

我已经在使用它,但它没有按要求工作,请准备好我的问题

以上是关于反应路由器基本代码拆分(获取第一个块,然后在后台异步获取其他块)的主要内容,如果未能解决你的问题,请参考以下文章

保护私有反应组件

vue路由传参的三种基本方式

React Router 代码拆分“随机”在加载块时失败

如何反应加载主页然后路由到其他人

如何调用另一个文件中的组件?反应原生

我对反应路由器的相对路径有困难。基本路径从位置栏中消失