I'm trying to apply code splitting to my React app. The below code is my routes with code splitting applied by Loadable
from react-loadable
. With the implementation, every time I access each page, the code chunk from webpack is properly loaded. However, when I access my webpage initially, it brings about screen flicker initially. After that, if I move to another page, no more screen flicker. It only happens when accessing my website initially.
Does anyone know why it's happening? Is there something wrong on my configuration?
By the way, I used server-side rendering with Node.js in my React app. Does it have something to do with screen flicker by code splitting?
routes.jsx
import React from "react";
import Loadable from "react-loadable";
import { Route, Switch } from "react-router-dom";
import NotFound from "routes/not-found";
const Landing = Loadable({
loader: () => import(/* webpackChunkName: "landing" */ "routes/landing"),
loading: () => null,
modules: ["landing"]
});
const About = Loadable({
loader: () => import(/* webpackChunkName: "about" */ "routes/about"),
loading: () => null,
modules: ["about"]
});
export default props => {
return (
<Switch>
<Route
exact
path="/"
render={routeProps => <Landing {...routeProps} options={options} />}
/>
{/* <Route exact path="/" component={Homepage} /> */}
<Route
exact
path="/about"
render={routeProps => <About {...routeProps} options={options} />}
/>
<Route component={NotFound} />
</Switch>
);
};
src/index.js
const { store, history } = createStore();
const generateClassName = createGenerateClassName();
const Application = (
<JssProvider generateClassName={generateClassName}>
<MuiThemeProvider theme={theme}>
<Provider store={store}>
<ConnectedRouter history={history}>
<Frontload noServerRender={true}>
<App />
</Frontload>
</ConnectedRouter>
</Provider>
</MuiThemeProvider>
</JssProvider>
);
const root = document.querySelector("#root");
if (root.hasChildNodes() === true) {
// If it's an SSR, we use hydrate to get fast page loads by just
// attaching event listeners after the initial render
Loadable.preloadReady().then(() => {
hydrate(Application, root, () => {
document.getElementById("jss-styles").remove();
});
});
} else {
// If we're not running on the server, just render like normal
render(Application, root);
}
the flickering is happening because the router don't have the source of your component when routing and it renders null
as you defined in loading
func provided to Loadable HOC
to prevent flickering you can render a Loading component that should look something like this: https://github.com/osamu38/react-loadable-router-example/blob/master/src/components/Loading.js
or you can preload all the pages onComponentDidMount like this (you should convert your component to class component for it):
componentDidMount = () => {
About.preload()
Landing.preload()
}