HTTP2 is here so this technique will be probably deprecated in the future. You could still use bundling for reducing the number of requests for a specific page but I don’t think it will be worth of it.
Right before we start with “reverse” optimisation, we can use bundling to help us organise our assets and serve less files to the client which will (should) result in faster website.
One of our services is Technical audit which covers various tests on both Frontend and Backend part of the client’s store. Since i’m Frontend Developer, performance is my key point during analysis.
Well, in theory that was great. Usually I was right about their expertise level but I was wrong about one thing – they didn’t “forgot” to turn these ON.
Explaining to the client that you would probably have to refactor 80% of the code to change that “simple option” is something I wouldn’t want to go through again.
Strange question, I know. But it does make sense because if I report it, I’ll have to fix it.
Just kidding, of course this was included in our report and was first thing I changed when we took over the project.
How did it go? Well, do you write articles about stuff that work as expected?
Magento 2 Bundling
I must note that official docs do not give us a lot of information and there are only few discussions online about it.
Therefore, I may be wrong in some of my conclusions so feel free to correct me in comments 🙂
For start, let’s see 2 proper ways to load assets in Magento 2.
In this example, you can see how assets are loaded on two different Magento pages – Homepage and product page.
As you can see on example above, requireJS loaded different assets through different pages while all bundles were loaded regardless of wether they are needed or not.
With RequireJS, we can load specific JS modules on specific pages which means you will load only necessarily assets and reduce number of requests.
While RequireJS did help us with reducing number of requests through the page, we still have few JS files being loaded and “few” in Magento 2 means 40-50. We need a way to merge those assets into just few files. We need to create 5 files out of 50.
Files are being loaded asynchronously but still, if we could merge these files into just few, we could improve performance even more.
Bundling comes as a problem solver since it is used to merge modules and it dependencies into single file.
Bundling denies main benefit of using module loaders such as RequireJS since assets aren’t loaded asynchronously. Bundles are included with <script> tag, inside <head> section of the page.
So, why use it?
With bundling we could decide on where to load specific bundle and that’s the best part of it! For example, we want to put all checkout-related stuff into one bundle and load it only on checkout page!
Well, Magento folks didn’t implement RequireJS optimizer which is required for ordering and organising module load across different pages. You can exclude some scripts from bundle but you CAN’T decide on bundle content for a specific page.
So, why use it?
You probably have so many questions in your head right now. So do I. And I’m still searching for the answers.
Here is a random Zen image, just to chill you down.
Bundling misses key features (imho) but you can still change few things in order to organize your bundles.
Bundle size and exclude list
In Vendor/Theme/etc/view.xml you can change bundle size and exclude some scripts from bundle.
Default size for bundle is 1MB.
Bundle size determines number of bundles that will be created. For example, if you have 4MB of script files and bundle size is set to 1MB, you will have 4 bundles created.
If number is too low, you will probably have 10 and more small bundles which will block each other during rendering so be careful with this.
Remember that bundles are not loaded asynchronously.
We can also exclude certain scripts from bundles. They will be loaded with RequireJS when needed.
Keep in mind that Luma and Blank themes have their own exclude lists and if you are not properly fallbacking and don’t have your own exclude list, bundles will be huge since all JS modules will be bundled, regardless of whether you need them or not.
<exclude> handle takes care of files that should be excluded from bundle. As far Magento 2 is concerned – since we can’t decide on bundle content for each page, at least we can exclude assets that will not be required through the whole site, therefore bundles will consist only files that are required everywhere. As you can see in above example (Luma theme exclude list), jQuery assets are probably required everywhere so i don’t understand idea behind excluding these from bundles. Probably Magento folks wanted to leave most important stuff under RequireJS control.
After we have configured our bundle size and exclude list, it is time that we turn bundling on and enjoy great performance impact.
We can turn bundling on here: Stores > configuration > advanced >developer
After bundling is ON, clear cache and switch to production mode (bundling will not work in “Developer” mode). Static files will be deployed and you will see your bundles being loaded on the Frontend.
What about performance?
We did a lot in order to reduce number of requests through the site. But, there is one small problem with performance.
This is Homepage of the Luma theme.
Testing was done on Magento 2.2.0 “dev” version, with following setting in Dev console (Chrome):
Before turning bundling ON:
- Number of JS requests : 137
- Size: 2.0MB
- Loadtime: 9.46sec
With bundling turned ON:
- Number of JS requests : 8
- Size: 4.2MB
- Loadtime: 20.12sec
Take a look at size and load time?
Reason? With RequireJS you load only needed JS files on a specific page. Bundling merges all JS assets and serves them on all pages.
I must say I am disappointed with bundling, especially with the fact that we don’t have RequireJS optimizer by default. Without it, whole idea behind bundling is missed.
- Bundles multiple files into single file
- negates benefits of using module loader
- you can’t define bundle content precisely
- you can’t decide in which pages which bundle will be loaded
I don’t see any reason we should use bundling right now.
Bundling will make sense in the future if Magento folks create additional functionalities for us to use.
We need configuration file where we will be able to decide on :
- number of bundles
- bundle size
- bundle content
- which pages specific bundle will be loaded
Thanks for reading and i hope we can roll up some discussion about this topic in comments 🙂