如何减少产品包的大小? [英] How to decrease prod bundle size?

查看:21
本文介绍了如何减少产品包的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的应用程序,由 angular-cli 初始化.

它显示了与 3 条路线相关的一些页面.我有3个组件.在这个页面的其中一个页面上,我使用 lodash 和 Angular 2 HTTP 模块来获取一些数据(使用 RxJS Observables、mapsubscribe).我使用一个简单的 *ngFor 来显示这些元素.

但是,尽管我的应用程序非常简单,但我得到了一个巨大的(在我看来)捆绑包和地图.我不谈论 gzip 版本,但在 gzip 之前谈论大小.此问题只是一般性建议查询.

一些测试结果:

ng 构建

<块引用>

哈希:8efac7d6208adb8641c1 时间:10129ms 块{0} main.bundle.js,main.bundle.map (main) 18.7 kB {3} [initial] [rendered]

块{1}styles.bundle.css、styles.bundle.map、styles.bundle.map(样式)155 kB {4} [initial] [rendered]

chunk {2} scripts.bundle.js、scripts.bundle.map(脚本)128 kB{4} [初始] [渲染]

chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 3.96 MB[初始] [渲染]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 字节[条目] [渲染]

等等:对于这样一个简单的应用程序,10Mb 的供应商捆绑包?

ng build --prod

<块引用>

哈希:09a5f095e33b2980e7cc 时间:23455ms 块{0}main.6273b0f04a07a1c2ad6c.bundle.js,main.6273b0f04a07a1c2ad6c.bundle.map (main) 18.3 kB {3} [初始][渲染]

块{1}styles.bfdaa4d8a4eb2d0cb019.bundle.css,样式.bfdaa4d8a4eb2d0cb019.bundle.map,style.bfdaa4d8a4eb2d0cb019.bundle.map(样式)154 kB {4} [初始][渲染]

块{2} scripts.c5b720a078e5464ec211.bundle.js,scripts.c5b720a078e5464ec211.bundle.map(脚本)128 kB {4} [初始][渲染]

块{3} vendor.07af2467307e17d85438.bundle.js,vendor.07af2467307e17d85438.bundle.map(供应商)3.96 MB [初始][渲染]

块{4} inline.a345391d459797f81820.bundle.js,inline.a345391d459797f81820.bundle.map (inline) 0 字节 [entry][渲染]

再等一等:生产的供应商捆绑包大小如此相似?

ng build --prod --aot

<块引用>

哈希:517e4425ff872bbe3e5b 时间:22856ms 块{0}main.95eadabace554e3c2b43.bundle.js,main.95eadabace554e3c2b43.bundle.map (main) 130 kB {3} [初始][渲染]

块{1}styles.e53a388ae1dd2b7f5434.bundle.css,style.e53a388ae1dd2b7f5434.bundle.map,样式.e53a388ae1dd2b7f5434.bundle.map(样式)154 kB {4} [初始][渲染]

块{2} scripts.e5c2c90547f3168a7564.bundle.js,scripts.e5c2c90547f3168a7564.bundle.map(脚本)128 kB {4} [初始][渲染]

块{3} vendor.41a6c1f57136df286f14.bundle.js,vendor.41a6c1f57136df286f14.bundle.map(供应商)2.75 MB [初始][渲染]

块{4} inline.97c0403c57a46c6a7920.bundle.js,inline.97c0403c57a46c6a7920.bundle.map (inline) 0 字节 [entry][渲染]

ng build --aot

<块引用>

哈希:040cc91df4df5ffc3c3f 时间:11011ms 块 {0} main.bundle.js,main.bundle.map (main) 130 kB {3} [initial] [rendered]

块{1}styles.bundle.css、styles.bundle.map、styles.bundle.map(样式)155 kB {4} [initial] [rendered]

chunk {2} scripts.bundle.js、scripts.bundle.map(脚本)128 kB{4} [初始] [渲染]

chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 2.75 MB[初始] [渲染]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 字节[条目] [渲染]

关于在 prod 上部署我的应用程序的几个问题:

  • 为什么供应商捆绑包如此庞大?
  • angular-cli 是否正确使用了摇树?
  • 如何改进此捆绑包的大小?
  • 是否需要 .map 文件?
  • 测试功能是否包含在捆绑包中?我在生产中不需要它们.
  • 一般性问题:推荐的打包工具是什么?也许 angular-cli(在后台使用 Webpack)不是最好的选择?我们能做得更好吗?

我在 Stack Overflow 上搜索了很多讨论,但没有找到任何通用问题.

解决方案

2020 年 2 月更新

由于这个答案很受关注,我认为最好用更新的 Angular 优化对其进行更新:

  1. 正如另一位回答者所说,ng build --prod --build-optimizer 对于使用低于 Angular v5 的人来说是一个不错的选择.对于较新的版本,默认情况下使用 ng build --prod
  2. 另一种选择是使用模块分块/延迟加载来更好地将您的应用程序分成更小的块
  3. Angular 9 中默认提供常春藤渲染引擎,它提供更好的包大小
  4. 确保您的第 3 方 deps 可以摇树.如果你还没有使用 Rxjs v6,你应该使用.
  5. 如果其他方法都失败了,请使用 webpack-bundle-analyzer 之类的工具来查看导致模块膨胀
  6. 检查文件是否被压缩

<小时>

有些人声称使用 AOT 编译可以将供应商包大小减少到 250kb.然而,在 BlackHoleGalaxy 的示例中,他使用 AOT 编译,并且仍然留下 2.75MB 的供应商包大小,ng build --prod --aot,比假定的 250kb 大 10 倍.即使您使用的是 v4.0,这也不是 angular2 应用程序的标准.对于真正关心性能的人来说,2.75MB 仍然太大,尤其是在移动设备上.

您可以采取一些措施来提高应用程序的性能:

1) AOT &摇树(angular-cli 开箱即用).使用 Angular 9 AOT 是在 prod 和 dev 环境中的默认设置.

2) 使用 Angular Universal A.K.A.服务器端渲染(不在 cli 中)

3) Web Workers(同样不是在 cli 中,而是一个非常需要的功能)
请参阅:https://github.com/angular/angular-cli/issues/2305

4) 服务工作者
请参阅:
https://github.com/angular/angular-cli/issues/4006

在单个应用程序中您可能不需要所有这些,但这些是当前用于优化 Angular 性能的一些选项.我相信/希望谷歌意识到性能方面的开箱即用的缺点,并计划在未来改进这一点.

这是一篇更深入地讨论我上面提到的一些概念的参考资料:

https://medium.com/@areai51/the-4-stages-of-perf-tuning-for-your-angular2-app-922ce5c1b294

I have a simple app, initialized by angular-cli.

It display some pages relative to 3 routes. I have 3 components. On one of this page I use lodash and Angular 2 HTTP modules to get some data (using RxJS Observables, map and subscribe). I display these elements using a simple *ngFor.

But, despite the fact my app is really simple, I get a huge (in my opinion) bundle package and maps. I don't talk about gzip versions though but size before gzipping. This question is just a general recommendations inquiry.

Some tests results:

ng build

Hash: 8efac7d6208adb8641c1 Time: 10129ms chunk {0} main.bundle.js, main.bundle.map (main) 18.7 kB {3} [initial] [rendered]

chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [initial] [rendered]

chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 kB {4} [initial] [rendered]

chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 3.96 MB [initial] [rendered]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 bytes [entry] [rendered]

Wait: 10Mb vendor bundle package for such a simple app?

ng build --prod

Hash: 09a5f095e33b2980e7cc Time: 23455ms chunk {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (main) 18.3 kB {3} [initial] [rendered]

chunk {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css, styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.bfdaa4d8a4eb2d0cb019.bundle.map (styles) 154 kB {4} [initial] [rendered]

chunk {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.bundle.map (scripts) 128 kB {4} [initial] [rendered]

chunk {3} vendor.07af2467307e17d85438.bundle.js, vendor.07af2467307e17d85438.bundle.map (vendor) 3.96 MB [initial] [rendered]

chunk {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (inline) 0 bytes [entry] [rendered]

Wait again: such a similar vendor bundle size for prod?

ng build --prod --aot

Hash: 517e4425ff872bbe3e5b Time: 22856ms chunk {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (main) 130 kB {3} [initial] [rendered]

chunk {1} styles.e53a388ae1dd2b7f5434.bundle.css, styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (styles) 154 kB {4} [initial] [rendered]

chunk {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (scripts) 128 kB {4} [initial] [rendered]

chunk {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map (vendor) 2.75 MB [initial] [rendered]

chunk {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map (inline) 0 bytes [entry] [rendered]

ng build --aot

Hash: 040cc91df4df5ffc3c3f Time: 11011ms chunk {0} main.bundle.js, main.bundle.map (main) 130 kB {3} [initial] [rendered]

chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [initial] [rendered]

chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 kB {4} [initial] [rendered]

chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 2.75 MB [initial] [rendered]

chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 bytes [entry] [rendered]

So a few questions for deploying my app on prod:

  • Why are the vendor bundles so huge?
  • Is tree shaking properly used by angular-cli?
  • How to improve this bundle size?
  • Are the .map files required?
  • Are the testing features included in bundles? I don't need them in prod.
  • Generic question: what are the recommanded tools to pack for prod? Maybe angular-cli (using Webpack in the background) is not the best option? Can we do better?

I searched many discussions on Stack Overflow, but I haven't found any generic question.

解决方案

Update February 2020

Since this answer got a lot of traction, I thought it would be best to update it with newer Angular optimizations:

  1. As another answerer said, ng build --prod --build-optimizer is a good option for people using less than Angular v5. For newer versions, this is done by default with ng build --prod
  2. Another option is to use module chunking/lazy loading to better split your application into smaller chunks
  3. Ivy rendering engine comes by default in Angular 9, it offers better bundle sizes
  4. Make sure your 3rd party deps are tree shakeable. If you're not using Rxjs v6 yet, you should be.
  5. If all else fails, use a tool like webpack-bundle-analyzer to see what is causing bloat in your modules
  6. Check if you files are gzipped


Some claims that using AOT compilation can reduce the vendor bundle size to 250kb. However, in BlackHoleGalaxy's example, he uses AOT compilation and is still left with a vendor bundle size of 2.75MB with ng build --prod --aot, 10x larger than the supposed 250kb. This is not out of the norm for angular2 applications, even if you are using v4.0. 2.75MB is still too large for anyone who really cares about performance, especially on a mobile device.

There are a few things you can do to help the performance of your application:

1) AOT & Tree Shaking (angular-cli does this out of the box). With Angular 9 AOT is by default on prod and dev environment.

2) Using Angular Universal A.K.A. server-side rendering (not in cli)

3) Web Workers (again, not in cli, but a very requested feature)
see: https://github.com/angular/angular-cli/issues/2305

4) Service Workers
see: https://github.com/angular/angular-cli/issues/4006

You may not need all of these in a single application, but these are some of the options that are currently present for optimizing Angular performance. I believe/hope Google is aware of the out of the box shortcomings in terms of performance and plans to improve this in the future.

Here is a reference that talks more in depth about some of the concepts i mentioned above:

https://medium.com/@areai51/the-4-stages-of-perf-tuning-for-your-angular2-app-922ce5c1b294

这篇关于如何减少产品包的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆