Angular2 CLI巨大的供应商包:如何提高prod的大小?

时间:2017-01-02 20:00:34

标签: angular webpack angular-cli

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

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

显示这些元素

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

一些测试结果:

ng build

  

哈希: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   (样式)155 kB {4} [初始] [渲染]

     

chunk {2} scripts.bundle.js,scripts.bundle.map(scripts)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 bytes   [输入] [渲染]

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

ng build --prod

  

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

     

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

     

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

     

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

     

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

再次等待: prod的类似供应商包大小?

ng build --prod --aot
  

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

     

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

     

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

     

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

     

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

ng build --aot
  

哈希:040cc91df4df5ffc3c3f时间: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   (样式)155 kB {4} [初始] [渲染]

     

chunk {2} scripts.bundle.js,scripts.bundle.map(scripts)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 bytes   [输入] [渲染]

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

  • 为什么供应商捆绑这么大?
  • 角度cli正在使用树摇动吗?
  • 如何改善这个捆绑尺寸?
  • 是否需要.map文件?
  • 捆绑包中是否包含测试功能?我不需要它们。
  • 一般性问题:为prod打包的推荐工具是什么?也许angular-cli(在后台使用webpack)不是最合适的?我可以做更多吗?

我搜索了有关Stack Overflow的许多讨论,但我找不到任何一般性问题。

14 个答案:

答案 0 :(得分:46)

2018年10月更新

由于这个答案有很大的吸引力,我认为最好用更新的Angular优化来更新它:

  1. 正如另一位回答者所说,对于使用少于Angular v5的人来说,ng build --prod --build-optimizer是一个不错的选择。对于较新版本,默认情况下会使用ng build --prod
  2. 完成此操作
  3. 另一种选择是使用模块分块/延迟加载来更好地将应用程序拆分成更小的块
  4. Ivy渲染引擎虽然尚未投入生产,但很快就能提供更好的捆绑尺寸
  5. 确保您的第三方代表树可以摇动。如果您还没有使用Rxjs v6,那么您应该是。
  6. 如果所有其他方法都失败了,请使用像webpack-bundle-analyzer这样的工具来查看模块中导致膨胀的原因
  7. 有些声称使用AOT编译可以将供应商包大小减少到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 A.K.A.服务器端呈现(不在cli中)

    3)网络工作者(再次,不是在cli,而是一个非常要求的功能)
      见:https://github.com/angular/angular-cli/issues/2305

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

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

    这是一个参考,它更深入地讨论了我上面提到的一些概念:

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

答案 1 :(得分:20)

使用最新的angular cli版本并使用命令 ng build --prod --build-optimizer 肯定会减少 prod env。

的构建大小

这就是构建优化器所做的工作:

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

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

注意:Angular 5的一个更新,ng build --prod会自动处理上述过程:)

答案 2 :(得分:11)

首先,供应商捆绑包很大,因为Angular 2依赖于很多库。 Angular 2 app is around 500KB的最小尺寸(在某些情况下为250KB,见底部帖子) angular-cli正确使用树摇动 包含.map文件,因为仅用于调试。此外,如果您使用热替换模块,请将其移除以减轻供应商的负担。

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

优化应用必须使用Ahead-of-time compilation,并将Angular 2应用缩小为 250KB

这是我创建的一个repo(github.com/JCornat/min-angular)来测试最小的Angular bundle大小,我得到 384kB 。我相信有很简单的方法来优化它。

使用AngularClass/angular-starter配置谈论大型应用程序,与上面的repo相同,我的大型应用程序( 150+组件)的捆绑包大小来自 8MB < / strong>(4MB没有地图文件)到 580kB

答案 3 :(得分:11)

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'

就个人而言,我仍然希望我的实用功能更小。例如。最小化后,flatten可以为您的捆绑提供1.2K。所以我一直在构建一系列简化的lodash功能。我flatten的实施有助于50 bytes。你可以在这里查看它是否适合你:https://github.com/simontonsoftware/micro-dash

答案 4 :(得分:6)

以下解决方案假设您使用nodejs为dist /文件夹提供服务。请在根级别使用以下app.js

IF value < 0 PRINT '0'  
ELSE PRINT 'value' ;  

确保安装依赖项;

const express = require('express'),http = require('http'),path = require('path'),compression = require('compression');

const app = express();

app.use(express.static(path.join(__dirname, 'dist')));
app.use(compression()) //compressing dist folder 
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist/index.html'));
})

const port = process.env.PORT || '4201';
app.set('port', port);

const server = http.createServer(app);
server.listen(port, () => console.log('Running at port ' + port))

现在构建应用

npm install compression --save
npm install express --save;
  

如果你想进一步压缩构建说减少300kb(约)   来自,然后按照以下流程;

ng build --prod --build-optimizer 文件夹中创建一个名为 vendor 的文件夹,在供应商文件夹中创建一个文件 src < / strong>并在其中粘贴以下代码;

rxjs.ts

然后在angular-cli应用程序中的 export {Subject} from 'rxjs/Subject'; export {Observable} from 'rxjs/Observable'; export {Subscription} from 'rxjs/Subscription'; 文件中添加以下内容。然后在tsconfig.json中添加以下json;

compilerOptions

这会使您的构建尺寸变得太小。在我的项目中,我将大小从11mb缩小到1mb。 希望它有所帮助

答案 5 :(得分:5)

我想分享的一件事是导入的库如何增加dist的大小。我导入了angular2-moment软件包,而我可以使用从@ angular / common导出的标准DatePipe进行所有日期时间格式化。

使用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} [姓名]   [render] chunk {2} styles.056656ed596d26ba0192.bundle.css   (样式)69字节{4} [初始] [渲染]块{3}   vendor.62c2cfe0ca794a5006d1.bundle.js(vendor)3.84 MB [initial]   [render] chunk {4} inline.0b9c3de53405d705e757.bundle.js(inline)   0字节[输入] [渲染]

删除Angular2-moment并改为使用DatePipe

  

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js(polyfills)191   kB {4} [initial] [rendered] chunk {1}   main.f2b62721788695a4655c.bundle.js(主要)2.2 MB {3} [姓名]   [render] chunk {2} styles.056656ed596d26ba0192.bundle.css   (样式)69字节{4} [初始] [渲染]块{3}   vendor.e1de06303258c58c9d01.bundle.js(vendor)3.35 MB [initial]   [render] chunk {4} inline.3ae24861b3637391ba70.bundle.js(inline)   0字节[输入] [渲染]

请注意,供应商捆绑已减少半兆字节!

即使您已熟悉外部库,也值得检查角度标准包可以执行的操作。

答案 6 :(得分:2)

减少捆绑的另一种方法是服务GZIP而不是JS。我们从2.6mb到543ko。

https://httpd.apache.org/docs/2.4/mod/mod_deflate.html

答案 7 :(得分:1)

这确实减小了我的体积:

ng build --prod --build-optimizer --optimization

运行此命令后,大小从1.7MB减小到1.2MB,但不足以满足我的生产目的。

我在facebook Messenger平台上工作,并且Messenger应用程序必须小于1MB才能在Messenger平台上运行。一直在努力寻找有效的摇树方法,但仍然没有运气。

答案 8 :(得分:1)

它的作品100% ng build --prod --aot --build-optimizer --vendor-chunk = true

答案 9 :(得分:0)

我有一个角5 +弹簧启动应用程序(application.properties 1.3+),借助压缩功能(下面提供了链接)能够将main.bundle.ts的大小从2.7 MB减少到530 KB。

默认情况下,--aot和--build-optimizer也以--prod模式启用,您无需分别指定它们。

https://stackoverflow.com/a/28216983/9491345

答案 10 :(得分:0)

请检查是否已将ng build --prod的配置命名为“ production”,因为它是ng build --configuration = production的简写 没有问题的答案解决了我的问题,因为问题就在屏幕正前方。我认为这可能很普遍。 我已将i18n重命名为所有配置,从而使该应用程序国际化。生产中。 然后,我假设使用ng build --prod进行了构建,并使用了默认优化,并且应该接近最佳值,但实际上只是ng build已执行,导致7mb捆绑包,而不是250kb。

答案 11 :(得分:0)

如果您使用的是Angular 8+,并且想要减小捆绑包的大小,则可以使用Ivy。 只需转到src / tsconfig.app.json并添加angularCompilerOptions参数即可,例如:

{
  "extends": ...,
  "compilerOptions":...,
  "exclude": ...,

/* add this one */ 
  "angularCompilerOptions": {
    "enableIvy": true
  }
}

答案 12 :(得分:0)

如果您已运行ng build --prod-您根本不应该拥有vendor个文件。

如果我只运行ng build-我会得到以下文件:

enter image description here

文件夹的总大小约为14MB。哇! :D

但是如果我运行ng build --prod-我会得到以下文件:

enter image description here

该文件夹的总大小为584K。

一个相同的代码。在这两种情况下,我都启用了常春藤。角度为8.2.13。

所以-我想您没有在构建命令中添加--prod吗?

答案 13 :(得分:0)

来自angular docs v9(https://angular.io/guide/workspace-config#alternate-build-configurations):

默认情况下,定义了生产配置,并生成了ng 该命令具有--prod选项,该选项使用此配置进行构建。的 生产配置会设置默认设置,以在 多种方式,例如捆绑文件最小化多余的空白删除注释和无效代码,并重写代码以使用简短, 匿名名称(“缩小” )。

此外,您可以使用@ angular-builders / custom-webpack:browser生成器压缩所有可部署内容,其中自定义webpack.config.js如下所示:

module.exports = {
  entry: {
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[hash].js'
  },
  plugins: [
    new CompressionPlugin({
      deleteOriginalAssets: true,
    })
  ]
};

此后,您将必须配置Web服务器以提供压缩内容,例如使用nginx,您必须添加到您的nginx.conf:

server {
    gzip on;
    gzip_types      text/plain application/xml;
    gzip_proxied    no-cache no-store private expired auth;
    gzip_min_length 1000;
    ...
}

在我的情况下,仅使用--prod in ng版本后,dist文件夹从25 mb缩小到5 mb,然后在压缩后进一步缩小到1.5 mb。