background

June 14, 2021

Analysis of Shopware 6 its JavaScript usage

Yireo Blog Post

Having worked with Shopware 6 now a bit, it is great to say that the default storefront (based on Twig and Bootstrap) performs quite well out of the box. But we can always to a bit better. So I sat down to review the JavaScript usage of Shopware 6. Here's the result of that analysis.

How to analyse? Webpack bundle analyzer

First of all, how to analyse all JavaScript? By default, all scripts are compiled and merged into a single file app.js. The key here is to realize that this merging is done by Webpack and Webpack is extensible through various plugins, one of them being the webpack-bundle-analyzer.

I didn't dive into how to add a Webpack plugin without making a core hack. For my purpose, adding a core hack was just fine. So I navigated into the folder vendor/shopware/storefront/Resources/app/storefront and ran the command npm install --save-dev webpack-bundle-analyzer.

Next, the vendor/shopware/storefront/Resources/app/storefront/webpack.config.js file was modified to add a new plugin instance (new BundleAnalyzerPlugin()) on top of the existing plugins. And we were good to go by running the following command :

PROJECT_ROOT=`pwd` npm --prefix vendor/shopware/storefront/Resources/app/storefront run production

This not only compiles all sources for production, but also opens up the Webpack Analyser screen in a new window.

Analysing the sources

In my default setup, the total JavaScript size was 750Kb uncompressed. Compressed this is okayish. But less is more. While the Shopware core team currently advocates the usage of vanilla JavaScript plus some Shopware-specific libraries, the libraries of jQuery and Bootstrap are still included as well. And they are quite heavy: jQuery adds 229Kb and Bootstrap JS adds 129Kb - almost half of the total JavaScript size.

Remove Bootstrap?

So is it possible to remove Bootstrap? Of course it is. I found that the file @Storefront/storefront/src/main.js contains the only occurrence of Bootstrap:

import 'bootstrap';

Bluntly removing it only lead to some easily solvable JavaScript errors, complaining about missing tooltips. And indeed, the file @Storefront/storefront/src/utility/tooltip/tooltip.util.js calls upon the jQuery method tooltip() (which requires the Bootstrap tooltip plugin. But this is easily fixed in the file @Storefront/storefront/src/main.js:

//import 'bootstrap';
import 'bootstrap/js/dist/tooltip';

This already lowers the JavaScript size quite a bit. A bit, because the core Bootstrap JS is still needed (which again requires jQuery as well). So maybe a better way would be to override the Shopware JavaScript plugin that governs [data-toggle="tooltip"] and get rid of Bootstrap entirely.

Remove jQuery?

In a similar way, jQuery can be imported as well:

import jQuery from 'jquery'
import $ from 'jquery'

And what is imported should be something we can remove as well, right? Unfortunately, things are not that simple. It appears that the import statement is only used by Bootstrap JS (which we tried to get rid of first). Besides importing jQuery the NPM-way, scripts can also make use of the global jQuery object (which is actually made possible by the Webpack configuration).

Searching for $ in the @Storefront/storefront/src/* folder leads to numerous hits: Tooltips (mentioned earlier), collapse plugins, cross selling, the date-picker and the modal effect. (Beware that sometimes the $ is not a reference to jQuery but the usage of template literals or just a random variable.) To summarize, it requires quite a bit of work to remove all of that. If you do so, you might just need to rewrite the entire JavaScript system.

Other libraries

For the date picker, Flatpickr (115Kb) is used. Are you not selling products with date options? Are you not keen to ask your customers for their birth date? Neither am I. So by removing the DatePicker plugin entirely, you will remove 115Kb.

The BaseSlider plugin makes use of TinySlider (100Kb). Perhaps by rewriting this into something else, you are able to again shave off some kilobytes. The same counts for the Hammer.js library (72Kb) used for the zoom effect in the ImageZoom plugin.

Overriding the main configuration

Step-by-step, we find out that there are quite heavy JavaScript libraries loaded in the default storefront, which could potentially be removed. If you are going to explore the possibilities here, it might be better to just let go of the default JavaScript file of the Storefront bundle. For this to work, copy the file @Storefront/storefront/src/main.js to your own theme and compile things from there. Additionally, make sure to skip the default JavaScript.

For this, change the script section in your theme.json file from the following:

"script": [
    "@Storefront",
    "app/storefront/dist/storefront/js/swag-example-theme.js"
],

into:

"script": [
    "app/storefront/dist/storefront/js/swag-example-theme.js"
],

Summary

In short, this blog is not trying to solve things permanently, but points into the direction of customizing JavaScript to your own likings. Let the tuning begin.

Posted on June 14, 2021

About the author

Author Jisse Reitsma

Jisse Reitsma is the founder of Yireo, extension developer, developer trainer and 3x Magento Master. His passion is for technology and open source. And he loves talking as well.

Sponsor Yireo

Looking for a training in-house?

Let's get to it!

We don't write too commercial stuff, we focus on the technology (which we love) and we regularly come up with innovative solutions. Via our newsletter, you can keep yourself up to date on all of this coolness. Subscribing only takes seconds.

Do not miss out on what we say

This will be the most interesting spam you have ever read

We don't write too commercial stuff, we focus on the technology (which we love) and we regularly come up with innovative solutions. Via our newsletter, you can keep yourself up to date on all of this coolness. Subscribing only takes seconds.