Angular Application Build Optimizations
So many users use our applications on their phones and on mobile internet. Others may be on wifi, but not have super fast speeds. Because of those constraints, one of the most important things we can do is ensure our application bundle size is as small as possible. I recently went down the road of optimizing these build sizes for the apps in our Nx workspace and realized a few things that I hope can help others.
My App Background
Our Nx workspace has 6 applications and about 90 libraries. A couple of the apps have many parts to them. But I realized recently that the time of ignoring the build size had passed. We were building our apps and ending with bundles that were between 4 and 5 mb. Here is a breakdown of the 6 apps, with their main chunk size and initial bundle size:
Obviously, these sizes are too big. There’s no reason to be shipping 4.5–5 MB of code to a user, at least in our case. So how do we fix this? I started by building one of the applications and analyzing what was making it so big. This can be done with the
--stats-json flag added to the build command:
ng build app-name --configuration production --stats-json
The app will be output in the dist folder, in our case:
./dist/apps/app-name. After building the app, you can use webpack-bundle-analyzer to see what is causing the app to be so large:
npx webpack-bundle-analyzer dist/apps/app-name/stats.json
A webpage will open up in your browser showing the different pieces that make up your application. The bigger the box, the bigger the effect on your bundle size.
You can search by name or zoom in to sections by clicking on them.
When I did this, there were 3 main culprits that were making my application so large: geo2zip, moment.js, and xlsx. The last two had been in the project for years, and the first was actually pretty new. I knew that if I removed these three packages, I could reduce the bundle size greatly. Luckily, I was given the green light to go ahead and work on the project.
I worked on it for a few days in a row. At the end, my apps were much smaller (sizes will be listed below) and I had several tips that may help each of you.
Tip 1: Plan Ahead
The first tip is to plan ahead. This one doesn’t help if you’ve already got big bundle sizes, but it will help you going forward. Don’t just add packages to your application without checking to see the impact it may have on your application. You can do that in a couple ways. First, you can use this cool site that Wes Bos showed me: bundlephobia.com. If I’d used this before adding geo2zip to my project, I’d have seen that I was adding at least 1.9MB my app size. That’s half the size of some of those apps! That’s crazy!
So, plan ahead. Make sure you can import just what you need from a package, and that it’s optimized for modern web development. Hint: if your import statement looks like this:
import * as geo2zip from 'geo2zip';
You’re importing a package that likely will have adverse effects on your bundle size.
Tip 2: Present a Precise Plan
It’s never a good time to spend several days working on things that likely the business or end users will never recognize. So much of the requests on a developer’s time is to fix urgent bugs or adding new features. This type of maintenance is obviously not that. So, it can be hard to convince your boss or your boss’s boss that this is necessary. But if you present the plan to them in a clear and precise manner, you’re more likely to be told you can take the time to fix things. Here’s a couple examples of how you might go about this, first a bad example and second a good one.
“Hey boss, our Angular application build sizes are too big. We should do something about that.”
“What do we need to do to fix it? How long will it take?”
“I don’t know yet. It might be a couple days or a couple weeks.”
“I don’t think we have that kind of time. We’ll have to wait for a while.”
“Hey boss, our Angular application build sizes are too big. We should do something about that. I was looking at it and I have an idea of what we need to do. There are 3 packages that we’re including in our project that are ballooning the size of the app. We can replace them and improve the build sizes.”
“That sounds great. How long will it take?”
“I estimate 2 days for package 1, 2 days for package 2, and 1 or 2 days for the third. I feel pretty confident we can have it done within a week.”
Now, the second option is clearly a better way to present the problem to your boss. It doesn’t guarantee that they will approve your request, but it does give them a clear picture of the work that needs to be done. They can take that information and look at priorities and determine if now is a good time for you to work on the project. Take a half hour and do some research before going to your boss.
Tip 3: Unit Tests!
This is another one that won’t help if you haven’t already been working on it ahead of time, but it’s never a bad time to start writing unit tests. In my case, we had pretty decent coverage of unit tests, especially on services and utility files. Pulling out a package and replacing it, then running the unit tests and seeing them still pass really helps in your confidence level that everything will continue to work. When I was replacing Moment, I had to make changes to about 85 files. Manually testing each file is difficult. Having unit tests cover those components and services and utilities saved so much time. We will still do some spot checking and may have a couple minor adjustments to make, but this saved a lot of time.
Start writing unit tests now if you don’t have any. Do it slowly, not all at once (that’s too overwhelming!). When you touch a component, add a unit test. Same with utilities and pipes and other pieces. Then if you need to refactor in any way you’re ready to go.
Tip 4: Set Budgets for the App Sizes
This one will be done for you automatically if you create a new application, but some of our apps were created before this was really a standard in Nx or the Angular CLI. If you don’t have budgets set, get your app within a reasonable size and then set the budgets. You can do it in the build configuration portion of your
angular.json file. There’s a warning size and an error size. When you build your applications, you’ll be alerted if the size of the app starts creeping up.
I’m sure I’ve missed a few things, but these were 4 tips that really helped me. I hope they help you. And before you go, here’s a breakdown of my apps post-optimization:
Our apps are now so much smaller. They are all between 25% to 40% of the size they were initially. There’s still work to do on some of the apps, but we’ve made great progress in a small amount of time.
If you have any tips for me, let me know! I’m always looking to learn more about how to optimize my Angular apps. Good luck!