Codesplitting with webpack in a Laravel project
Code splitting with Webpack
I make the strong assumption here that you use webpack to bundle your code, which is the default bundler in Laravel. Perhaps you can configure other module bundlers as well, but I only have experience with webpack.
According to the documentation of webpack on code splitting, there are three ways to apply code splitting to your code. This post will discuss the way I implemented code splitting using the ‘dynamic imports’ approach in our codebase. We use this approach as it seems easier compared to the other options.
In app.js, we load jQuery into the page followed by the responsive menu (on every page). On the homepage we require a slider and on a bunch of other pages we load a module scrollArrow.
Before watching the lightning talk by Sean Larkin at Vue Conf US, I had no idea where to begin with code splitting. As it turns out, code splitting comes in very handy when you have specific pieces of code on specific pages (split per route). Additionally, a piece of code that is only executed after clicking a button (‘temporal’ is how Sean Larkin called it) is also ready to be code splitted.
Splitting code on routes
If we want to apply code splitting to the
my-owl-carousel module, (line 10–13 in
app.js) it has to be written as an ES6 module. Then we need to use the dynamic import syntax inside the if statement that defines the homepage ‘route’:
We use a regular expression to check that we are on the homepage. Then we apply the new import syntax (note that it is not a function). Additionally, we use some special, recommended comments that are used by webpack:
webpackChunkName defines the name of the compiled chunk of code. In this case we end up with a named chunk
my-owl-carousel.js, while leaving this comment out will enumerate the chunks (1.js, 2.js etc).
webpackPrefetch comment tells webpack that the module may be prefetched. This means the module will be loaded in the idle time of the browser, so the user won’t notice it! However, this is a Laravel project where Laravel-mix (wrapper around webpack) is used to compile the code. The webpackPrefetch comment is available from webpack >= 4.6. Unfortunately, Laravel-mix uses an older version of webpack at the moment. However Laravel-mix support for webpack 4 is in the works. Hence, I already add the webpack comment to benefit from once it comes to Laravel-mix.
The import syntax returns a promise. Once it resolves, we grap the module and apply the default function we exported in the module.
To make the property
webpackChunkName work, I had to extend the output property of webpack in the webpack.mix.js file. I added the property
chunkFilename like this (line 18):
This way, the compiled modules arrive neatly in my public/js folder as you see below.
Splitting ‘temporal’ code
We have a responsive menu on the website, but the code that shows and hides the menu only has to be available after clicking the menu button. A perfect way to apply code splitting on this ‘temporal’ code. The code looks like this:
Once the mobile menu link, defined by the selector
#header_mobile a is clicked, the menu-mobile module is imported dynamically.
Routes and temporals
In the final example we’ll use code splitting twice. The use case here is that we have a bunch of pages where we have a button. Clicking the button scrolls down the page and shows a form. Hence, the scroll-and-show-form module is dynamically imported only on these pages:
scroll-and-show-form module itself looks like this:
Hence, only after a button click, the form is shown to the user and the
form-validation module is imported.
Summary and wrap up
In this post I discussed two ways to apply code splitting using dynamic imports. The first example treated code splitting based on the route to make sure we only load the code on pages that need it. The second example treated code splitting on ‘temporal code’. This enables us to only load the code once it is needed (comparable to lazy loading of images). The last example combines these two approaches.