首页 文章

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

提问于
浏览
86

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

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

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

一些测试结果:

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(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] [渲染]

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

ng build --prod

哈希: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 (脚本)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(内联)0字节[entry] [已呈现]

再等一下: such a similar vendor bundle size for prod?

ng build --prod --aot

哈希:517e4425ff872bbe3e5b时间: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 (脚本)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 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] [渲染]

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

  • 为什么供应商捆绑如此庞大?

  • angular-cli正确使用了树吗?

  • 如何改善这个捆绑尺寸?

  • Are the .map files required?

  • 捆绑包中是否包含测试功能? 生产环境 中我不需要它们 .

  • 一般问题:为prod打包的推荐工具是什么?也许angular-cli(在后台使用webpack)不是最合适的?我可以做更多吗?

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

8 回答

  • 8

    使用最新的角度cli版本并使用命令 ng build --prod --build-optimizer 它绝对是 reduce prod env的构建大小 .

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

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

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

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

  • 10

    我有一个有角度的5 spring 启动应用程序(application.properties 1.3),在压缩的帮助下(下面的链接)能够将main.bundle.ts大小从2.7 MB减小到530 KB .

    此外,默认情况下--aot和--build-optimizer都使用--prod模式启用,您无需单独指定它们 .

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

  • 29

    首先,供应商捆绑是巨大的,因为Angular 2依赖于大量的库 . Angular 2 app is around 500KB的最小尺寸(在某些情况下为250KB,见底部帖子) .
    树摇是正确使用 angular-cli .
    not 包含 .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+ components )的包大小从 8MB (没有 Map 文件的4MB)变为 580kB .

  • 2

    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

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

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

  • 18

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

    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;
    

    现在构建应用程序

    ng build --prod --build-optimizer
    

    如果你想进一步压缩构建说减少300kb(大约),则按照以下过程;

    src 文件夹中创建一个名为 vendor 的文件夹,在vendor文件夹中创建一个文件 rxjs.ts 并将下面的代码粘贴到其中;

    export {Subject} from 'rxjs/Subject';
    export {Observable} from 'rxjs/Observable';
    export {Subscription} from 'rxjs/Subscription';
    

    然后在angular-cli应用程序中的 tsconfig.json 文件中添加以下内容 . 然后在 compilerOptions 中添加以下json;

    "paths": {
          "rxjs": [
            "./vendor/rxjs.ts"
          ]
        }
    

    这将使您的构建大小变得太小 . 在我的项目中,我将大小从11mb缩小到1mb . 希望能帮助到你

  • 6

    Update October 2018

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

    • 正如另一位回答者所说,对于使用少于Angular v5的人来说, ng build --prod --build-optimizer 是一个不错的选择 . 对于较新的版本,默认情况下使用 ng build --prod

    • 另一种选择是使用模块分块/延迟加载来更好地将应用程序拆分成更小的块

    • 常 Spring 藤渲染引擎虽然尚未投入 生产环境 ,但很快就会提供更好的捆绑尺寸

    • 确保你的第三方派对是树可以摇动的 . 如果你还没有使用Rxjs v6,你应该是 .

    • 如果所有其他方法都失败了,请使用像webpack-bundle-analyzer这样的工具来查看模块中导致膨胀的原因


    一些声称使用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)Web Workers(再次,不是在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

  • 0

    我想分享的一件事是导入的库如何增加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} [initial] [rendered ] chunk {2} styles.056656ed596d26ba0192.bundle.css(styles)69字节{4} [initial] [rendered] chunk {3} vendor.62c2cfe0ca794a5006d1.bundle.js(vendor)3.84 MB [initial] [rendered] chunk { 4} inline.0b9c3de53405d705e757.bundle.js(内联)0字节[entry] [render]

    删除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.056656ed596d26ba0192.bundle.css(styles)69字节{4} [initial] [rendered] chunk {3} vendor.e1de06303258c58c9d01.bundle.js(vendor)3.35 MB [initial] [rendered] chunk {4} inline.3ae24861b3637391ba70 .bundle.js(内联)0字节[条目] [呈现]

    请注意,供应商包已减少 half a Megabyte!

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

相关问题