Chapters
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Webpack Bundle Analyzer
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeEach time we add a new Stimulus controller - either by adding a new file to assets/controllers/
, or via the controllers.json
file when we install a new Symfony UX package - all the code from that controller - and any modules it imports - are added to the set of JavaScript that's included and downloaded on every page. For example, this sweetalert2
code is currently only used on the cart page... but it's downloaded on every page.
But you know how the old saying goes: premature optimization is the root of all evil. Or maybe it's money... or running out of cake...
My point is: this is not necessarily a problem. And the benefit of how this all works is huge! We can write a controller, add a corresponding data-controller
element to any page - even loading it via Ajax - and it will work. That is a game changer both for reliability and simplicity.
However, it may not be a bad idea to look at what's inside of our compiled JavaScript files - the stuff that's in the public/build/
directory. And we can easily do that with Webpack.
Dumping a Stats File from Webpack
Find your terminal, go to the tab that has Encore and hit Control+C. Now run:
yarn run --silent build --json > stats.json
I know, that looks a bit funny. The main command in there is yarn run build
. That executes the build
script that's in our package.json
file. So basically, yarn run build
is a shortcut to do a production build. We're doing a production build because the point of this command - the --json
flag is the magic - is to dump a huge amount of information into a new stats.json
file about our built files. And if we're going to optimize our files, it'll be more realistic if we look at a production build.
Installing and Using webpack-bundle-analyzer
But... this file... isn't exactly readable. Fortunately, instead of parsing through this data by hand, we can use a visualization library. Install it with:
yarn add webpack-bundle-analyzer --dev
This adds a new executable to our app. When it finishes, we can run yarn webpack-bundle-analyzer
, point it at the stats.json
file and then tell it where our built files are located: public/build
.
yarn webpack-bundle-analyzer stats.json public/build
Hit it. And... woh! This starts a new, temporary web-server at http://127.0.0.1:8888 and opens our browser. You can see this back on the terminal. If it didn't open a browser for you, just go directly to that URL.
Oh, I can feel the power. This shows every built file and what's inside of it. For example, the biggest file is this 801.js
file. The filenames in a production build are purposely short and cryptic. An app.js
file is also being output as well as a tiny runtime.js
file.
Looking at this... it's pretty obvious that the biggest thing is chart.js
. And, though this specific tool doesn't tell us, I know that moment
is also here because it's being imported by chart.js
.
By the way, as we talked about way back at the start of the tutorial, the reason we see 3 files is that Encore - via Webpack - automatically splits our code into pieces. Head back to the homepage... and view the HTML source. Yep! Our page includes 3 script tags for the 3 files we saw a second ago. These represent the built code for our one Webpack entry called app
.
What's important for us is that the contents of these three files are being loaded on every single page.
Can we somehow improve this situation so that our users need to download less JavaScript for every page?
We can! Next, let's learn a native Webpack feature - async imports - that can help us lazily load JavaScript in any file. After that, I'll show you a super amazing trick that's special to Stimulus and Symfony.
4 Comments
Hey Benjamin,
It's always tricky to make things work on Windows. Thanks for sharing your solution
Cheers!
...Not webpack-bundle-analyser
which does exist but isn't related
Ha! Who would imagine... thanks for sharing it to others. Cheers!
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"composer/package-versions-deprecated": "1.11.99.1", // 1.11.99.1
"doctrine/annotations": "^1.0", // 1.11.1
"doctrine/doctrine-bundle": "^2.2", // 2.2.3
"doctrine/doctrine-migrations-bundle": "^3.0", // 3.0.2
"doctrine/orm": "^2.8", // 2.8.1
"phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
"sensio/framework-extra-bundle": "^5.6", // v5.6.1
"symfony/asset": "5.2.*", // v5.2.3
"symfony/console": "5.2.*", // v5.2.3
"symfony/dotenv": "5.2.*", // v5.2.3
"symfony/flex": "^1.3.1", // v1.21.6
"symfony/form": "5.2.*", // v5.2.3
"symfony/framework-bundle": "5.2.*", // v5.2.3
"symfony/property-access": "5.2.*", // v5.2.3
"symfony/property-info": "5.2.*", // v5.2.3
"symfony/proxy-manager-bridge": "5.2.*", // v5.2.3
"symfony/security-bundle": "5.2.*", // v5.2.3
"symfony/serializer": "5.2.*", // v5.2.3
"symfony/twig-bundle": "5.2.*", // v5.2.3
"symfony/ux-chartjs": "^1.1", // v1.2.0
"symfony/validator": "5.2.*", // v5.2.3
"symfony/webpack-encore-bundle": "^1.9", // v1.11.1
"symfony/yaml": "5.2.*", // v5.2.3
"twig/extra-bundle": "^2.12|^3.0", // v3.2.1
"twig/intl-extra": "^3.2", // v3.2.1
"twig/twig": "^2.12|^3.0" // v3.2.1
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.0
"symfony/debug-bundle": "^5.2", // v5.2.3
"symfony/maker-bundle": "^1.27", // v1.30.0
"symfony/monolog-bundle": "^3.0", // v3.6.0
"symfony/stopwatch": "^5.2", // v5.2.3
"symfony/var-dumper": "^5.2", // v5.2.3
"symfony/web-profiler-bundle": "^5.2" // v5.2.3
}
}
What JavaScript libraries does this tutorial use?
// package.json
{
"devDependencies": {
"@babel/preset-react": "^7.0.0", // 7.12.13
"@popperjs/core": "^2.9.1", // 2.9.1
"@symfony/stimulus-bridge": "^2.0.0", // 2.1.0
"@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/Resources/assets", // 1.1.0
"@symfony/webpack-encore": "^1.0.0", // 1.0.4
"bootstrap": "^5.0.0-beta2", // 5.0.0-beta2
"core-js": "^3.0.0", // 3.8.3
"jquery": "^3.6.0", // 3.6.0
"react": "^17.0.1", // 17.0.1
"react-dom": "^17.0.1", // 17.0.1
"regenerator-runtime": "^0.13.2", // 0.13.7
"stimulus": "^2.0.0", // 2.0.0
"stimulus-autocomplete": "^2.0.1-phylor-6095f2a9", // 2.0.1-phylor-6095f2a9
"stimulus-use": "^0.24.0-1", // 0.24.0-1
"sweetalert2": "^10.13.0", // 10.14.0
"webpack-bundle-analyzer": "^4.4.0", // 4.4.0
"webpack-notifier": "^1.6.0" // 1.13.0
}
}
On my windows 10 env I've got a syntax error runing webpack-bundle-analyzer command because the json file had a BOM.
Couldn't read webpack bundle stats from "D:\STINO\code-stimulus\mine\stats.json":<br />SyntaxError: Unexpected token � in JSON at position 0
I removed the BOM and it worked !