Severe increase in watch compile time when moving to Laravel Mix v6 & Vue 3

Viewed 455

Edit:

A bit more information after trying to tackle this again 6 months later:

  • I'm now developing my Vue components within Storybook, which also watches and hot reloads changes to my components. Changes appear in Storybook almost instantly and around 1-2 seconds before my application with yarn hot.
  • My CI/CD pipeline is failing to build the production build ("mix --production") due to an Allocation failed - JavaScript heap out of memory error. I've increased the physical amount of memory on my build server but something has definitely changed between Mix 5 and Mix 6, which could be related to this issue.

Original Question:

I'm updating my Laravel 8 project from Vue 2 and Laravel Mix 5 to Vue 3 and Laravel Mix 6, and I've noticed that the recompile-time when a component is modified to be significantly longer than with Mix 5.

Before Upgrading

{
    "laravel-mix": "^5.0.1",
    "vue": "^2.5.17",
    "vue-template-compiler": "^2.6.10"
}

Before the upgrade, my app.js and webpack.mix.js files looked like this and re-compile times were in the order of ~100ms when running yarn run hot.

// package.json
{
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js"
}
// app.js
window.Vue = require('vue');

// Register Components
Vue.component('my-component', () => import(/* webpackPrefetch: true */ './MyComponent'));
Vue.component('my-component', () => import(/* webpackPrefetch: true */ './MyComponent'));
Vue.component('my-component', () => import(/* webpackPrefetch: true */ './MyComponent'));
Vue.component('my-component', () => import(/* webpackPrefetch: true */ './MyComponent'));
Vue.component('my-component', () => import(/* webpackPrefetch: true */ './MyComponent'));
Vue.component('my-component', () => import(/* webpackPrefetch: true */ './MyComponent'));
Vue.component('my-component', () => import(/* webpackPrefetch: true */ './MyComponent'));
// ... There are around 100 components loaded here
new Vue({
  el: '#app',
});
// webpack.mix.js
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js');

After Upgrading

{
    "vue": "^3.1.5",
    "vue-loader": "^16.3.3",
    "laravel-mix": "^6.0.27"
}

Once the upgrade of Mix and Vue was complete, running yarn run hot saw re-compile times around 2-3 seconds, which is a huge performance hit.

// package.json
"hot": "mix watch --hot",
// app.js
const app = createApp({});

// Register Components
app.component('my-component', defineAsyncComponent(() => import(/* webpackPrefetch: true */ './MyComponent')));
app.component('my-component', defineAsyncComponent(() => import(/* webpackPrefetch: true */ './MyComponent')));
app.component('my-component', defineAsyncComponent(() => import(/* webpackPrefetch: true */ './MyComponent')));
app.component('my-component', defineAsyncComponent(() => import(/* webpackPrefetch: true */ './MyComponent')));
app.component('my-component', defineAsyncComponent(() => import(/* webpackPrefetch: true */ './MyComponent')));
app.component('my-component', defineAsyncComponent(() => import(/* webpackPrefetch: true */ './MyComponent')));
app.component('my-component', defineAsyncComponent(() => import(/* webpackPrefetch: true */ './MyComponent')));
// ... There are around 100 components loaded here

app.mount('#app');
// webpack.mix.js
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js').vue();

I've narrowed it down to the sheer number of components in the app.js file (which wasn't a problem before upgrading). If I reduce the number of components registered in app.js with Mix 6, the re-compile times reduce significantly. It seems to be re-compiling all components when only one of them changes, which wasn't the behaviour with the previous configuration.

1 Answers

Did you followed the steps in the Laravel mix 5 to 6 upgrade guide?

The vue function mix.vue() has been added in v6, and also you can extract the vendor libraries using extract function mix.extract() to improve compile performance.

Related