laravel mix - lazy loading Vue components


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.


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 \

tutorial commit

2. bable config

Create a file in the root of your Laravel application called .babelrc with the following contents.

    "plugins": ["syntax-dynamic-import"]

tutorial commit

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')

tutorial commit

4. app.js

Instead of loading components in the standard way,


We need to use the lazy loading import method.

    () => import(
        /* webpackChunkName: "example-component" */

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.

tutorial commit

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: {    
    mounted() {
        console.log('Component mounted.')   

The ExampleSubComponent will be included in public/js/example-component.bundle.js rather than public/js/app.js.