Shared modules in Angular or how not to shoot in your leg

Sergey Gultyayev
2 min readFeb 24, 2021

--

A modular structure in Angular is well known and I bet everyone who have worked with this framework has heard of such a conception as a SharedModule.

However, while this concept seems easy it’s commonly misused/misunderstood.

The problem

Have you ever tried optimizing initial load bundle size? Have you ever struggled to cut off some KBs to make the initial bundle smaller? What if I say that most of those issues might have been solved if SharedModule wasn’t used in a way it usually is?

In the official docs it’s said

Creating shared modules allows you to organize and streamline your code. You can put commonly used directives, pipes, and components into one module and then import just that module wherever you need it in other parts of your app.

However, I see that most people (and I was one of those for a while) read this as “Take all ever re-used components/pipes/directives in more than one module into a SharedModule” which is a bad idea.

Here is why:

  1. You have a super-big-module which may contain up to 60–70% of the whole application.
  2. It’s common to place components/pipes/directives/services at module where they are declared/provided/exported.
  3. This leads us to having a super big folder with non-related units.
  4. Once this module is imported to the app.module or any other module which is not lazy loaded the initial bundle will contain this whole mess.
  5. Initial bundle contains hundreds of kilobytes of code which is not used in currently loaded modules.

What’s more alerting is that the “core” (the part which is loaded eagerly and then loads some modules in a lazy fashion) app may use only 1–2 components or even none from the SharedModule, however all this will be included in the initial bundle. Thus, instead of 10–50 Kb of components you actually need you end up with more than few MBs, because as I mentioned earlier SharedModule contains almost everything.

Developers of libraries like Angular Material and other big Angular libs have already come to the solution. The solution is called “Feature Modules”.

Basically this is an extension of previously mentioned “SharedModule”. However, “Feature Modules” concept says us to create many small modules which are cohesive and contain only code that needed to make their feature work (e.g. MatInputModule and so on). This concept is very simple and great at the same time, because our parts of an application are able to decide for themselves what to import.

This way one ultra-big SharedModule is split into tens of FeatureModules which are imported only where needed. This allows the Webpack to create optimal bundles and what’s more important more slim initial bundle size.

TL;DR

Stop using one SharedModules. Split it into multiple modules each of which would solve some small problem (like MatInputModule gives you only the input). This way you get smaller bundle sizes (all modules import only those feature modules they actually need), much better organized folder structure.

--

--

Sergey Gultyayev
Sergey Gultyayev

Written by Sergey Gultyayev

A front-end developer who uses Angular as a main framework and loves it

Responses (2)