Magento 2 Javascript Bundling - Group/Combine JS files

Magento 2 javascript bundling plays an important role in optimizing website performance. By merging multiple JavaScript files into one, it reduces server requests. Thus, you can enhance loading speed by making several processes become fewer requests.

Covering key aspects like why JavaScript bundling is useful, adjusting bundle size, creating exclusion lists, enabling bundling, and checking performance, this guide aims to help you better optimize your Magento 2 stores.

Key Takeaways about JavaScript bundling in Magento 2

  • Delve into the importance of bundling for enhancing user experience and increasing search engine rankings.

  • Find out more about how JavaScript bundling in Magento 2 boosts website performance to make page loads faster through merging files.

  • Understand clearly the systematic procedure for enabling JavaScript bundling.

  • Discover tips for fine-tuning themes with JavaScript bundling to provide a customized user experience.

  • Learn the method to exclude specific files from bundling and understand its importance for optimizing loading processes.

  • Get answers to common questions about JavaScript bundling FAQs, encompassing techniques for bundling all JS files and popular bundlers.

What is Javascript bundling?

Javascript bundling is an optimization technique that is used in today’s module-based development to group individual files to decrease the number of HTTP requests which are needed to load a page. This is acquired by merging multiple JavaScript files together into one file. Besides, it denies the main advantage of using module loaders such as RequireJS which is loading files asynchronously.

Why use Javascript bundling?

Before explaining why bundling should be used, let’s have a glance at the two ways in which assets are loaded in Magento 2.

In the following image, you will see the way assets are loaded on two different pages in Magento, which are the Homepage and the Product page.

js

With requireJS, different assets are loaded through different pages while all bundles are loaded even if they are not needed. In other words, you are able to reduce the number of requests by only loading necessary assets. However, there are still a huge number of JS files being loaded. If these assets could be merged into just a few files, the performance could be improved even more.

This is where Bundling comes in. It is a great solution to merge modules and their dependencies into individual files. Therefore, you could decide the place to load a specific bundle. For instance, you can put all checkout-related files into a bundle and load that bundle on the checkout page. Besides, if you want to merge JS modules, you will have to use bundling, as, without it, you can only merge Javascript files which are not being loaded via RequireJS.

Despite the fact that bundling is missing key features, you can still change a couple of things to organize your bundles better.

How bundling works

The Magento 2 JS Bundling mechanism functions by consolidating all JavaScript bundles into a limited number of bundles, which are then loaded for all pages. During page rendering, the browser synchronously downloads all the bundles, and it adheres to the Magento Standard, requiring each bundle to be at least 100KB. For convenience, exclusions of specific files that cannot be processed in bundling can be implemented using the etc/view.xml configuration. Below is a code snippet from the Luma theme, illustrating the types of files that should be excluded from the bundling process.

<exclude>
    <item type="file">Lib::jquery/jquery.min.js</item>
    <item type="file">Lib::jquery/jquery-ui-1.9.2.js</item>
    <item type="file">Lib::jquery/jquery.ba-hashchange.min.js</item>
    <item type="file">Lib::jquery/jquery.details.js</item>
    <item type="file">Lib::jquery/jquery.details.min.js</item>
    <item type="file">Lib::jquery/jquery.hoverIntent.js</item>
    <item type="file">Lib::jquery/colorpicker/js/colorpicker.js</item>
    <item type="file">Lib::requirejs/require.js</item>
    <item type="file">Lib::requirejs/text.js</item>
    <item type="file">Lib::date-format-normalizer.js</item>
    <item type="file">Lib::legacy-build.min.js</item>
    <item type="file">Lib::mage/captcha.js</item>
    <item type="file">Lib::mage/dropdown_old.js</item>
    <item type="file">Lib::mage/list.js</item>
    <item type="file">Lib::mage/loader_old.js</item>
    <item type="file">Lib::mage/webapi.js</item>
    <item type="file">Lib::mage/zoom.js</item>
    <item type="file">Lib::mage/translate-inline-vde.js</item>
    <item type="file">Lib::mage/requirejs/mixins.js</item>
    <item type="file">Lib::mage/requirejs/static.js</item>
    <item type="file">Magento_Customer::js/zxcvbn.js</item>
    <item type="file">Magento_Catalog::js/zoom.js</item>
    <item type="file">Magento_Ui::js/lib/step-wizard.js</item>
    <item type="file">Magento_Ui::js/form/element/ui-select.js</item>
    <item type="file">Magento_Ui::js/form/element/file-uploader.js</item>
    <item type="file">Magento_Ui::js/form/components/insert.js</item>
    <item type="file">Magento_Ui::js/form/components/insert-listing.js</item>
    <item type="directory">Magento_Ui::js/timeline</item>
    <item type="directory">Magento_Ui::js/grid</item>
    <item type="directory">Magento_Ui::js/dynamic-rows</item>
    <item type="directory">Magento_Ui::templates/timeline</item>
    <item type="directory">Magento_Ui::templates/grid</item>
    <item type="directory">Magento_Ui::templates/dynamic-rows</item>
    <item type="directory">Magento_Swagger::swagger-ui</item>
    <item type="directory">Lib::modernizr</item>
    <item type="directory">Lib::tiny_mce</item>
    <item type="directory">Lib::varien</item>
    <item type="directory">Lib::jquery/editableMultiselect</item>
    <item type="directory">Lib::jquery/jstree</item>
    <item type="directory">Lib::jquery/fileUploader</item>
    <item type="directory">Lib::css</item>
    <item type="directory">Lib::lib</item>
    <item type="directory">Lib::extjs</item>
    <item type="directory">Lib::prototype</item>
    <item type="directory">Lib::scriptaculous</item>
    <item type="directory">Lib::less</item>
    <item type="directory">Lib::mage/adminhtml</item>
    <item type="directory">Lib::mage/backend</item>
</exclude>

In this approach, although we have the ability to exclude certain scripts from the bundle, we face a limitation in loading only page-specific bundles. This limitation contributes to delays in loading data related to elements like the mini-cart or other checkout-related information after the initial page load.

Furthermore, this approach has an impact on increasing the file size of the bundle, especially when enabling the Minify/Merge JS option in the backend. Enabling the Minify JS option results in the file (bundle0.min.js) reaching a substantial size, such as 8 MB. Magento JS Bundling, by default, leads to an increase in the file size of the bundle, prompting consideration of alternative options like Advanced JS Bundling. Logically, loading all JS, much of which is not necessary for specific pages, may contribute to these challenges.

Steps to Enable Bundling

JavaScript bundling is only active in production mode. To enable it, follow these steps using the CLI:

1. Switch to Production Mode: Navigate to the installation directory and run:

bin/magento deploy:mode:set production

2. Enable JavaScript Bundling:

bin/magento config:set dev/js/enable_js_bundling 1

3. Minify JavaScript Files:

bin/magento config:set dev/js/minify_files 1

4. Enable Cache Busting for Static Files: This ensures users always get the latest version of assets:

bin/magento config:set dev/static/sign 1

5. Disable JavaScript File Merging: Bundling cannot occur if files are merged, so disable merging:

bin/magento config:set dev/js/merge_files 0

6. Deploy Static Content: After making these changes in production mode, deploy the static view files:

bin/magento setup:static-content:deploy

7. Clear the Cache: Finally, clear the cache to apply your changes:

bin/magento cache:clean config

Configure Bundle size and exclude list

The bundle size can be changed as well as several scripts can be excluded from the bundle in Vendor/Theme/etc/view.xml.

bundle size

1MB is the default size for a bundle. Please remember that the number of bundles that will be created are determined by bundle size. For instance, four bundles will be created if you have 4MB of script files and set the bundle size to 1MB.

However, you need to be really careful cause if the number is too low, 10 or more small bundles will be created and block each other during rendering.

Please keep in mind that bundles are loaded synchronously.

Excluding files

Besides, certain scripts can also be excluded from bundles. You can use RequireJS to load them if you need to.

Remember that two themes, which are Luma and Blank, have their own exclude lists, so if you do not fall back properly as well as do not have an exclude list for your own, all JS modules will be bundled even if you do not need them. This would make the bundles become huge.

The handle <exclude> will deal with all the files which should be excluded from the bundle. In Magento 2, bundle content on each page cannot be decided; however, the assets that will not be required through the whole site can be excluded. Because of that, bundles will only consist of the files that are required.

Tips to Personalize Your Theme

To customize your theme, you can modify the etc/view.xml file. Here’s a guide on combining JavaScript files for your Luma theme:

  • Create a New Page: Design a page with the desired layout structure you want to adjust.
  • Compare JavaScript Files: Identify the JavaScript files loaded on this page.
  • Exclude Unnecessary Files: Compare the loaded files with your existing JavaScript. Create a list of files you can exclude to optimize your theme’s performance.

Check Performance

After activating the bundling, the number of requests through the site has reduced significantly. However, there is still one problem with performance. You will see it when comparing the performance before and after turning on the Javascript bundling.

The following picture is the Luma theme’s Homepage. The testing was completed on the 2.2.0 “dev” version of Magento. The following setting is in the Dev console (Chrome):

check performance

Before activating the bundling, the number of JS requests is 137, the size is 2.0MB and the load time is 9.46sec

performance checking

Meanwhile, if you turn on the Javascript bundling, the number of JS requests is cut down dramatically to 8 requests, but the total file size of generated bundles is becoming even larger than the file size of all non-bundled JavaScript files on the front end. Also, the load time is also increased from 9.46 to 20.12sec. This is mainly because while RequireJS helps you load only necessary JS files on a specific page, bundling merges all JS assets and serves them on all pages.

Advanced bundling Javascript

Advanced Bundling consolidates all packages and delivers them as a single unit, enhancing speed performance while decreasing server requests and bundle size for every loaded browser page.

To implement Advanced Bundling for JavaScript, it’s essential to create specific bundles for each page, focusing on those that are crucial, such as the Home page, Category Page, Product Page, Cart, and Checkout Page.

For instance, you could create bundles like one for dependencies shared across all pages, another for CMS-only pages, a separate bundle for Catalog-only pages, an additional one for Search-only pages, and a specific bundle for Checkout pages.

Required tools

Requirejs

Node.js

PhantomJS (optional)

FAQs

1. What was the first JavaScript bundler?

The first JavaScript bundler was called “+=”, which was used for concatenation. For a long time, it met all the necessary requirements.

2. What was JavaScript’s original name?

Brendan Eich created JavaScript at Netscape Communications Corporation. It was initially named Mocha, then changed to LiveScript, and eventually became JavaScript. The renaming occurred around the same time Netscape added Java technology support to its browser, Netscape Navigator.

3. Why should we use JavaScript bundling?

JavaScript bundling combines multiple JavaScript files into a single file to reduce the number of server requests made by the browser. This process improves performance by minimizing file size and speeding up page load times.

4. What factors should you consider when selecting a hosting service for a Magento 2 store with JavaScript bundling enabled?

When selecting a hosting service for a Magento 2 store that uses JavaScript bundling, consider the following: ensure the hosting service supports server-side dependencies like Node.js and necessary libraries or tools. Additionally, choose a provider with sufficient resources to manage increased website traffic due to enhanced performance.

Conclusion

In conclusion, you can see the biggest benefit you will get when using Javascript bundling is that this tool helps you bundle multiple files into single files. However, the drawbacks outweigh the advantages. More specifically:

  • It negates the benefits of using a module loader.
  • Bundles’ file size is much larger than all non-bundled javascript file sizes in total.
  • You will not be able to define bundle content accurately.
  • The pages and the bundle which will be loaded cannot be decided.

I hope this post can provide you with basic knowledge about Javascript Bundling and how you can use it to better your Magento 2 performance.

Thank you for reading! I’m pleased to see your discussion in the comment section.

Image Description
With over a decade of experience crafting innovative tech solutions for ecommerce businesses built on Magento, Jacker is the mastermind behind our secure and well-functioned extensions. With his expertise in building user-friendly interfaces and robust back-end systems, Mageplaza was able to deliver exceptional Magento solutions and services for over 122K+ customers around the world.
x