Реагировать на разделение базового кода маршрутизатора (получить первый фрагмент, а затем асинхронно получить другие фрагменты в фоновом режиме)
Я использую приложение create-response-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
в браузере - Сначала получить домашний кусок
- затем другие три фрагмента асинхронно в фоновом режиме
на самом деле я тестирую производительность через расширение lighthouse chrome. Разделение базового кода маршрутизатора дает мне хорошую производительность первой страницы, но когда я открываю вторую страницу, это требует времени, но не должно занимать времени. Я думаю, что это возможно, если мы получим асинхронные другие фрагменты в фоновом режиме после загрузки первого фрагмента
2 ответа
Вы можете добиться этого, используя подсказки ресурсов браузера (предварительная загрузка и предварительная выборка).
Если вы используете webpack, вам пригодятся волшебные комментарии. вы можете попробовать что-то вроде этого:
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-адрес, он будет предварительно загружать домашний модуль и предварительно выбирать три других модуля с низким приоритетом.
Если вам нужно динамическое поведение, вы можете попробовать использовать плагин: 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;
}
};
Оберните маршрутизатор функцией 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>
<Suspense fallback={<Loading/>}>
<Router>
<HomeModule path="/home" />
<AuthModule path="/auth" />
<ProfileModule path="/profile" />
<MerchantModule path="/merchant" />
</Router>
</Suspense>