How to Optimize VueJs + Vuetify SPA Builds with Laravel MIX

Srilal S. Siriwardhane
4 min readOct 26, 2021

--

If you have ever built an application with Laravel as backend and Vue/Vuetify for frontend you know how “Heavy” the UI Js Bundles get even with GZIP. Vuetify alone will eat up more than half a megabyte. That may sound not a lot but for your users, it is. That 0.5MB will cause your application’s First content full paint to lag for at least a second or two on an average connection. BUT remember if that’s the average, a half of your yours will have worse loading times than that. (You can use https://bundlephobia.com/ to get a rough idea on loading times and sizes but these values will be quite different in reality)

So, what’s the solution?

Well, there are multiple solutions. But most ignored and overlooked one is trying to tree shake and reduce the size of your Js bundles even if you split it into few parts. And sometimes splitting Js bundles may increase the loading times depending on well, dependencies! Staring with Tree shaking will be always a good bet.

Many not know but with most recent version of Laravel mix, you can do Tree Shaking for VueJs UIs that are using Vuetify UI Library. To get started you will need to install few dependencies and update few that may already be installed in your project.

Prerequisites

First make sure your Laravel Mix version is upgraded to the latest version and at least 6.X. upgrading mix is bit messy if you are using an older version. But sticking to the official upgrade guide from here will sort most of these issues out.

Special Note: As of writing this there is a compatibility issue with Sass library. Simply use no more than version 1.32.X. The more recent version will break your builds and Dev Runs.

And remember to update your build scripts as well.

Configure Vuetify Import Options

The Vuetify tree shaking only happen if we import Vuetify libraries instead the whole Vuetify itself. This allows for the Vuetify loader to import only the used components and saves the build sizes. In the place where you have imported Vuetify, make sure to import Vuetify by only the Vuetify Libs. And you don’t need to import the CSS now because the Vuetify Loader will do it for you.

import Vuetify from ‘vuetify/lib’;

Laravel Mix Bundle Analyzer

Now let’s install webpack bundle analyzer. What’s the points if we can’t measure how much bytes we saved by doing all this! We cannot use the regular bundle analyzer, we need “Laravel-mix-bundle-analyzer” a wrapper around the Webpack bundle analyzer with compatibility with Laravel Mix.

· You can install it by running:

npm i laravel-mix-bundle-analyzer — save-dev

· More info and full details:

Vuetify Mix Extension

this one will help the Laravel Mix with Vuetify. it’s a wrapper around official vuetify webpack plugin for Mix. It also provides a key option in tree shaking for Vuetify.

· You can install it by running:

npm i vuetifyjs-mix-extension — save-dev

· More info and full details:

Vuetify Loader

This will automatically import all Vuetify components as you use them so unused components can be safely ignored. thus, decreasing build size.

· You can install it by running:

npm i vuetify-loader — save-dev

· More info and full details:

Configure Webpack Options

now we have everything we need. Let’s configure the Webpack configurations in Webpack.mix.js file.

First import the 3 libraries we just installed on the top of the file.

const mix = require(‘laravel-mix’);require(‘vuetifyjs-mix-extension’)require(‘laravel-mix-bundle-analyzer’);require(‘vuetify-loader’);

to only run the bundle analyzer when we do a production build, let’s add check to see if it’s a production build and run only if so. Mix API provides a way to do this easily.

if (mix.inProduction()) {    mix.bundleAnalyzer();}

And to inform the Laravel Mix to utilize Sass-loader and Vuetify-loader we need to add it to the default exports.

module.exports = {
module: {
rules: [
{
test: /\.s(c|a)ss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: {
indentedSyntax: true
},
},
},
],
},
],
},
configureWebpack: {
plugins: [
],
},
}

For configuring Hot Reload feature add, (if you are using Laragon or similar, add your virtual host address to host property instead of localhost)

mix.options({
hmrOptions: {
host: 'localhost',
port: 8080,
},
});

Finally, we can configure the actual Vue and Vuetify options in Mix to allow for a tree shake. We need to tell Mix that we are using Vue and Vuetify and the Vuetify is using Vuetify Loader.

mix.js(‘resources/js/App.js’, ‘public/js’)    .vuetify(‘vuetify-loader’)    .vue()    .sass(‘resources/sass/app.scss’, ‘public/css’);

And if you have more than one Vue Instances using different Vuetify imports,

mix.js(‘resources/js/AppOne.js’, ‘public/js’)    .vuetify(‘vuetify-loader’)    .vue()    .js(‘resources/js/AppTwo.js’, ‘public/js’)    .vuetify(‘vuetify-loader’)    .vue()    .sass(‘resources/sass/app.scss’, ‘public/css’);

Congratulations! now you have more optimized Vue/Vuetify Build! try running a production build and compare the sizes.

--

--

Srilal S. Siriwardhane
Srilal S. Siriwardhane

No responses yet