This article describes an experiment that shows why using the SharedMaterial module in all Angular modules is a bad idea that leads to an increased bundle size.
In this blog post, I will talk about a mistake I have made and have seen many developers doing it as well, which is a shared Material Module. I am sure if you used Angular Material, you still have a SharedMaterial Module in your project, time to remove it.
I am working on a new project which has many modules, and it has more than 20k Lines of Code, and I was working on making some modules as Lazy Loaded modules. I realized we are using the SharedMaterial module in all modules. First, I thought its ok, but I tried to do an experiment which proved its a bad idea.
In my last project where we had our custom components like Grid, Tables, Forms and I did ended up using a big Shared Material Module, as all the components were written on top of Angular Material Component. And now it’s time to prove myself wrong that it was not a good approach.
Let’s create a new App, and we will cover what’s wrong with this approach and how it increases the bundle size. We will be using webpack-bundle-analyzer to check the bundle size. Run the below command to create a new App. Make sure you are using the latest Angular CLI
ng new demoapp
next install webpack-bundle-analyzer using the below command
Add the below code into department and employee component respectively
One more change is needed in department.component.ts add the below property :
panelOpenState = false;
Now, we need to add some Material module into our employee, and department module as well to avoid the build error, and this is where most of us decide to create a SharedMaterial module like one below.
ng g m shared/material --flat true
and add the below code into the new module:
Now include the newly create MaterialModule into employee and department module.
Now run the analyzer again, you can see 216 KB has increased.
Now to optimize the app, the next approach we take is lazy load the modules. Let’s convert the employee and department module to lazy loaded module.
Remove the EmployeeModule and DepartmentModule from app.module.ts remove the import statement and from the import array as well.
This is the code after removing both modules
Next, configure the employee and department as a lazy-loaded module. Add the below code to app-routing.module.ts
Next, add the below code in employee-routing.module.ts
And similar changes in department-routing.module.ts
Let’s change app.component.html to use routerLink to lazy-load these 2 modules.
Now run the analyzer again and check the bundle size. After lazy loading, the bundle size should be reduced, but it increased by around 70KB.
Now, let’s remove the Shared Material module and import only the modules which are needed. In employee.module.ts import MatFormFieldModule and MatSelectModule and in department.module.ts import MatExpansionModule and MatFormFieldModule delete the shared module and run the command to analyze the bundle size. In this example, we save around 40KB.
I did a similar experiment in my current project, and the bundle size was reduced by around 200KB, remember when it comes to the web every single KB matters. So, I would suggest and try in your app refactor and share your experience.