React router base code-splitting (get first chunk and then get other chunks async in background)

不羁的心 提交于 2021-01-27 19:56:08

问题


I am using create-react-app. I want to react-router base code-splitting but I want to get the first chunk which user open in browser and then get other chunks asynchronously in the background

Routes

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} />

suppose, if user open /home in the browser then home chunk will be loaded first after loading first chunk call other chunks asynchronously in the background

Required Output

  1. Open /home in browser
  2. Get home chunk first
  3. then other three chunks asynchronously in the background

actually I am testing performance through lighthouse chrome extension. router base code-splitting gives me the good performance of the first page but when I open second page it takes time but it should not take time. I think it is possible if we get other chunks async in the background after loading first chunk


回答1:


You can achieve this by using browser resource hints(Preload and prefetch)

If you are using webpack, then magic comments will be helpful. you can try something like this:

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

In the above case, no matter what the url is it will preload the homemodule and prefetch the other three modules with low priority.

If you want the dynamic behaviour, you can try using the plugin: https://github.com/SebastianS90/webpack-prefetch-chunk

After adding the plugin, you can use webpack_require.pfc method to load the chunks in background.

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;
  }
};



回答2:


Wrap the Router with Suspense that takes a fallback(show some content while loading chunk, if it was not yet loaded)...

 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>

            <Suspense fallback={<Loading/>}>
                <Router>
                  <HomeModule path="/home" />
                  <AuthModule path="/auth" />
                  <ProfileModule path="/profile" />
                  <MerchantModule path="/merchant" />
                </Router>
            </Suspense>


来源:https://stackoverflow.com/questions/61931283/react-router-base-code-splitting-get-first-chunk-and-then-get-other-chunks-asyn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!