I created my app with create-react-app
.
In my website, I used lazy loading for page components :
import HomePage from '~/containers/pages/HomePage/Loadable';
import RestaurantPage from '~/containers/pages/RestaurantPage/Loadable';
// other routes
const RoutesList = ({ history }) => {
history.listen(() => {
window.scrollTo(0, 0);
});
return (
<DefaultLayout history={history}>
<Switch>
<Route path="/restaurant/:slug" component={RestaurantPage} />
// other routes
<Route exact path="/" component={HomePage} />
<Route component={ErrorPage} statusCode="404" />
</Switch>
</DefaultLayout>
);
};
And my Loadable component looks like this :
import React from 'react';
import LoadingIndicator from '~/components/common/LoadingIndicator';
import loadable from '~/utils/loadable';
export default loadable(() => import('./index'), {
fallback: <LoadingIndicator />,
});
With this for lazy component :
/* eslint-disable react/jsx-props-no-spreading */
import React, { lazy, Suspense } from 'react';
const loadable = (importFunc, { fallback = null } = { fallback: null }) => {
const LazyComponent = lazy(importFunc);
return (props) => (
<Suspense fallback={fallback}>
<LazyComponent {...props} />
</Suspense>
);
};
export default loadable;
So my problem is, the code splitting works fine in firefox. When clicking a link in a the menu, the separated chunk files are loading only when accessing the new page.
But in chrome, every chunk files are loaded.
So I found the solution. But it was tricky and linked to my configuration.
So what happened is that I'm using a custom webpack config (with craco), and I addded a plugin, PreloadWebpackPlugin
to add preload to fonts, images.
By default, this plugin also add "preload" to chunks. But webpack is smart, it doesn't add the not needed chunk files in the first load.
But what was happening is that I had the hot module reload file was listing all chunk files (so it can restart when there is a change), and this config was "preloading" them all.
So the only thing I had to do is :
webpackConfig.plugins.push(
new PreloadWebpackPlugin({
rel: 'preload',
include: 'allAssets',
fileWhitelist: [/main.chunk.js/, /\.webp/, /\.woff2/, /\.woff/],
}),
);
Only add preload to main chunk file.
Now it works.