Vue Router lazy loading and chunking
You normally use Webpack to handle your app builds, by default, Webpack create one file for all assets, even CSS.
The first step, maybe, is separate styles from app.js in their own CSS files.
To do this, we’ll use the Webpack plugin MiniCssExtractPlugin which we’ll configure like this:
This forces Webpack to extract CSS into separated files, for example
If you use vue-cli, this is the default config for Webpack.
For simple apps it is a good idea keep all your built code into a single file, because client’s browser loads
app.css the first time user accesses your app and keep it in cache, next access the file will be served from local browser’s cache (until cache expire).
But when your application starts to grow the
app.js will be huge, slowing down the page loading. There will even be parts of the app that are never used, for example “pages” (in this context think pages as Vue page component, not static pages) forbidden for regular users.
In this case a good solution is chunking your
app.js using async components for page components. You can split every page into different files which will be loaded when user navigates to route.
This strategy uses the Webpack’s code splitting feature.
In Vue router configuration you just do
const routes = [
Webpack now will create a separated file for your page components. But this way the user receives no feedback about the loading process. We could improve the router using a loading component.
An async component must provide a Promise.resolve. When you write
() => import('./views/HomeComponent') implicit you return a Promise that resolves the component. But if you want to use the handling loading state you need to return an explicit Promise
import LoadingComponent from './LoadingComponent'
As you can see, we use a Promise.resolve that returns component render function.
data and children are necessary to pass props, attributes and events to component More info
With these changes, when the user navigate to
/ firstly, the app shows the LoadingComponent and then, when the component is fully loaded, shows it.
Finally, say that you can group the components in the same chunk using the following notation.
import(/* webpackChunkName: "group-main" */ './HomeComponent.vue')