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 anAllocation failed - JavaScript heap out of memoryerror. 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.