Angular2 CLI巨大的供应商捆绑:如何提高产品尺寸?

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

它显示了一些相对于3条路线的页面。 我有3个组件。 在这个页面上,我使用lodash和Angular2 Http模块来获取一些数据(使用Rxjs Observables,map和subscribe)。 我用一个简单的ngFor来显示这些元素。

但是,尽pipe我的应用程序真的很简单,但我得到了一个巨大的(在我看来)捆绑软件包和地图。 我不讨论gzip版本,但是在gzip之前大小。 这个问题只是一个普遍的build议问。

一些testing结果:

build立

Hash:8efac7d6208adb8641c1时间: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]

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

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

块{4} inline.bundle.js,inline.bundle.map(内联)0字节[条目] [呈现]

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

ng build –prod

Hash:09a5f095e33b2980e7cc时间: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]

块{4} inline.a345391d459797f81820.bundle.js,inline.a345391d459797f81820.bundle.map(内联)0字节[条目] [呈现]

再等一等: 这样一个类似的供应商捆绑大小prod?

 ng build --prod --aot 

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

chunk {1}个样式.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 

哈希:040cc91df4df5ffc3c3f时间:11011ms块{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]

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

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

块{4} inline.bundle.js,inline.bundle.map(内联)0字节[条目] [呈现]

所以在prod上部署我的应用程序有几个问题:

  • 为什么供应商捆绑如此之大?
  • 树是否正确使用由angularcli?
  • 如何提高这个包的大小?
  • 需要.map文件吗?
  • 捆绑包中是否包含testingfunction? 我不需要他们的产品。
  • 一般问题:推荐的工具是什么? 也许angular-cli(在后台使用webpack)不是最合适的吗? 我们能做更多吗?

我search了堆栈溢出的许多讨论,但我没有发现任何通用的问题。

这里不是一个逆向的人,但我认为接受的答案釉了很多重要的信息。 雅克声称,使用AOT编译可以减less供应商捆绑大小为250kb。 然而,在BlackHoleGalaxy的例子中,他使用了AOT编译,并且还剩下一个2.75MB的供应商包,其中ng build --prod --aot ,比所假定的250kb大10倍。 即使您使用的是v4.0,这对于angular2应用程序来说也是不符合规范的。 对于那些真正关心性能的人来说,2.75MB仍然太大,特别是在移动设备上。

有几件事你可以做,以帮助你的应用程序的性能:

1)AOT&Tree Shaking(angular落cli这个开箱即用)

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

3)networking工作者(再次,不是cli,但非常需要的function)
请参阅: https : //github.com/angular/angular-cli/issues/2305

4)服务人员
请参阅: https : //github.com/angular/angular-cli/issues/4006

您可能不需要在单个应用程序中使用所有这些function,但是这些是目前优化Angular性能的一些选项。 我相信/希望Google意识到性能方面的缺陷,并计划在未来改进这一点。

这里有一个参考资料,更深入地谈到我上面提到的一些概念:

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

首先,供应商捆绑是巨大的,因为Angular 2依赖于很多库。 Angular 2应用程序的最小大小约为500KB (有些情况下为250KB,请参见底部的post)。
树摇晃适当地由angular-cli使用。
不要包含.map文件,因为仅用于debugging。 而且,如果使用热更换模块,请将其取下以减轻供应商的负担。

为了打包生产,我个人使用Webpack (并且angular-cli也依赖于它 ),因为您可以真正configure everything来进行优化或debugging。
如果你想使用Webpack ,我同意第一个观点有点棘手,但是看网上的教程,你不会感到失望。
否则,使用angular-cli ,这可以很好地完成工作。

使用前期编译是优化应用程序的必要条件,并将Angular 2应用程序缩小到250KB

这里是我创build的回购( github.com/JCornat/minangular )来testing最小的Angular bundle大小,我获得了384kB 。 我相信有一个简单的方法来优化它。

在讨论大应用时,使用AngularClass / angular-starterconfiguration,与上面的回购相同,我的大应用( 150+组件 )的包大小从8MB (没有映射文件的4MB)变为580kB

使用最新的angular度cli版本和使用命令ng build –prod –build-optimizer它肯定会减less prod env的构build大小。

这就是构build优化器所做的事情:

构build优化器有两个主要的工作。 首先,我们可以将应用程序的某些部分标记为纯粹的,这样可以改善现有工具提供的树震动,从而删除不需要的应用程序的其他部分。

构build优化器所做的第二件事是从您的应用程序的运行时代码中删除Angular装饰器。 装饰器由编译器使用,在运行时不需要,可以删除。 这些作业中的每一个都会减lessJavaScript包的大小,并为用户提高应用程序的启动速度。

Lodash可以根据您从中导入的方式向您的软件包贡献一大堆代码。 例如:

 // includes the entire package (very large) import * as _ from 'lodash'; // depending on your buildchain, may still include the entire package import { flatten } from 'lodash'; // imports only the code needed for `flatten` import flatten from 'lodash-es/flatten' 

就我个人而言,我还是希望从我的实用function中find更小的脚印,所以我一直在build立一系列简化的lodashfunction。 你可以在这里查看它是否适用于你: https : //github.com/simontonsoftware/micro-dash

我希望分享的一件事情是导入的库如何增加dist的大小。 我已经导入了angular2-moment包,而我可以使用从@ angular / common导出的标准DatePipe来完成所需的所有date时间格式。

用Angular2-Moment "angular2-moment": "^1.6.0",

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js(polyfills)191 kB {4} [initial] [rendered] chunk {1} main.e7496551a26816427b68.bundle.js(main)2.2 MB {3} [initial] [rendered] chunk {2} styles.556656ed596d26ba0192.bundle.css(styles)69 bytes {4} [initial] [rendered] chunk {3} vendor.62c2cfe0ca794a5006d1.bundle.js(vendor)3.84 MB [initial] [rendered] chunk {4 } inline.0b9c3de53405d705e757.bundle.js(inline)0 bytes [entry] [rendered]

删除Angular2-moment并使用DatePipe代替

{0} polyfills.036982dc15bb5fc67cb8.bundle.js(polyfills)191 kB {4} [initial] [rendered] chunk {1} main.f2b62721788695a4655c.bundle.js(main)2.2 MB {3} [initial] [rendered] chunk {2} styles.556656ed596d26ba0192.bundle.css(styles)69 bytes {4} [initial] [rendered] chunk {3} vendor.e1de06303258c58c9d01.bundle.js(vendor)3.35 MB [original] [rendered] chunk {4 } inline.3ae24861b3637391ba70.bundle.js(inline)0 bytes [entry] [rendered]

注意供应商捆绑已经减less了半兆!

要指出的是,即使你已经熟悉了一个外部库,你也应该检查一下angular度标准包能做什么。