laravel mix - lazy loading Vue components
why?
Lazy loading components gives a great performance improvement. Larger components can take ages to load and result in an unusable page for a few seconds while the massive app.js file is loaded.
how?
You can follow these steps on the tutorial repo .
1. babel plugins
You will need to add both the babel-plugin-dynamic-import-webpack and babel-plugin-syntax-dynamic-import packages to your package.json
$ npm install --save-dev \
babel-plugin-dynamic-import-webpack \
babel-plugin-syntax-dynamic-import
2. bable config
Create a file in the root of your Laravel application called .babelrc with the following contents.
{
"plugins": ["syntax-dynamic-import"]
}
3. webpack config
Update your webpack.mix.js file to the following:
let mix = require('laravel-mix');
// Override mix internal webpack output configuration
mix.config.webpackConfig.output = {
chunkFilename: 'js/[name].bundle.js',
publicPath: '/',
};
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css')
.version();
4. app.js
Instead of loading components in the standard way,
Vue.component(
'example-component',
require('./components/ExampleComponent.vue')
);
We need to use the lazy loading import method.
Vue.component(
'example-component',
() => import(
/* webpackChunkName: "example-component" */
'./components/ExampleComponent.vue'
)
);
The import()
function will
load the Vue component in dynamically, so it is only loaded by the browser when
actually used.
/* webpackChunkName: "example-component" */
is used to specify the name of
the bundle file webpack generates. In this instance a file called
example-component.bundle.js
is created in the public/js/
directory.
5. done
Now you have lazy loading components, your application will be a little more responsive on first load and when each Vue component initialises, the browser will load the component’s file chunk.
a note on sub-components
Sub-components will be included in the bundle of the parent component they are imported into.
Say we add a new component to ExampleComponent.vue
import ExampleSubComponent from './ExampleSubComponent.vue';
export default {
components: {
ExampleSubComponent,
},
mounted() {
console.log('Component mounted.')
}
};
The ExampleSubComponent
will be included in public/js/example-component.bundle.js
rather than public/js/app.js
.