ChatGPT解决这个技术问题 Extra ChatGPT

如何减小产品包大小?

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

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

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

一些测试结果:

构建

哈希:8efac7d6208adb8641c1 时间:10129ms 块 {0} main.bundle.js,main.bundle.map(主)18.7 kB {3} [初始] [渲染] 块 {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 ]

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

ng build --prod

哈希:09a5f095e33b2980e7cc 时间:23455ms 块 {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (main) 18.3 kB {3} [initial] [rendered] chunk {1} styles.bfdaa4d8a.cs4styles.bfdaa4d8a.cs4 , styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.bfdaa4d8a4eb2d0cb019.bundle.map (styles) 154 kB {4} [initial] [rendered] chunk {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.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 bytes [entry] [rendered]

再等一下:prod 的供应商捆绑大小如此相似?

ng build --prod --aot

哈希:517e4425ff872bbe3e5b 时间:22856ms 块 {0} main.95eadbace554e3c2b43.bundle.js,main.95eadbace554e3c2b43.bundle.map(主)130 kB {3} [初始] [渲染] 块 {1} styles.e53a388ae1dd2b7f543. , styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (styles) 154 kB {4} [initial] [rendered] chunk {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a755.脚本)128 kB {4} [initial] [rendered] chunk {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map(供应商)2.75 MB [initial] [rendered] chunk {4} inline.97c0403c57a46c6a7920 .bundle.js, inline.97c0403c57a46c6a7920.bundle.map (inline) 0 bytes [entry] [rendered]

ng build --aot

哈希:040cc91df4df5ffc3c3f 时间:11011 毫秒块 {0} main.bundle.js,main.bundle.map(主)130 kB {3} [初始] [渲染] 块 {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 ]

所以有几个关于在产品上部署我的应用程序的问题:

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

angular-cli 是否正确使用摇树?

如何提高这个捆绑包的大小?

是否需要 .map 文件?

捆绑包中是否包含测试功能?我在产品中不需要它们。

一般问题:推荐的产品包装工具是什么?也许 angular-cli(在后台使用 Webpack)不是最好的选择?我们能做得更好吗?

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

要了解有关 Angular 2 应用优化的更多信息,请查看以下内容:github.com/mgechev/angular-performance-checklist#introduction
但我不认为我们应该那么在意,angular-cli 会发展,事情会做得越来越好。如果您需要一些 angular-cli 没有的功能,只需在他们的 repo 中提交一个问题:github.com/angular/angular-cli
虽然我认为@Timathon 在某些方面是正确的,但如果有人试图将 Angular2 部署到生产环境中,他们应该关心包的大小,因为这会直接影响应用程序的性能。角度性能清单是一个很好的资源,可以查看可以改进的地方。 Angular 团队正在努力减少捆绑包的大小。很高兴看到它的去向!

P
Patricio Vargas

2020 年 2 月更新

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

正如另一位回答者所说, ng build --prod --build-optimizer 对于使用低于 Angular v5 的人来说是一个不错的选择。对于较新的版本,默认情况下这是使用 ng build --prod 完成的另一个选项是使用模块分块/延迟加载来更好地将应用程序拆分为更小的块 Ivy 渲染引擎默认出现在 Angular 9 中,它提供了更好的包大小确保你的第 3 方部门是可摇树的。如果你还没有使用 Rxjs v6,你应该使用。如果一切都失败了,请使用 webpack-bundle-analyzer 之类的工具来查看导致模块膨胀的原因 检查文件是否已压缩

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

您可以做一些事情来帮助提高应用程序的性能:

1) AOT & Tree Shaking(angular-cli 开箱即用)。使用 Angular 9,AOT 默认在 prod 和 dev 环境中。

2)使用Angular Universal AKA服务器端渲染(不在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


我的最小项目是 384kB,请参阅 github.com/JCornat/min-angular 我确信有一种简单的方法可以优化它,但它接近 250kB!
@JacquesCornat 看起来不错!但是您的应用程序只有一个组件。问题是如何管理捆绑大小或更大的应用程序。通常 AOT 并没有足够地减少包的大小,人们被迫寻找其他方式来优化。我强烈建议大家查看 webpack-bundle-analyzer。一种非常有用/简单的方法来查看导致膨胀的原因
遗憾的是,sw-precache 等实用程序拒绝处理大于 2MB 的供应商捆绑包。
@JackClancy“问题是如何管理捆绑包大小或更大的应用程序”。不,他的问题是“如何提高这个捆绑包的大小?”他正在谈论他的具有 3 个组件的最小应用程序。无论如何,谈到大包,使用 AngularClass/angular-starter 配置,和我的仓库一样,我的大应用包大小从 8MB(4MB 没有地图文件)到 580kB。
谢谢,你救了我。 --prod 将应用程序大小从 6Mb 减少到 1.2Mb。仍然不完美,但可以接受,因为它仅供桌面使用。
P
Patricio Vargas

使用最新的 Angular cli 版本并使用命令 ng build --prod --build-optimizer 它肯定会减少 prod env 的构建大小。

这就是构建优化器在后台所做的:

构建优化器有两个主要工作。首先,我们能够将应用程序的某些部分标记为纯,这改进了现有工具提供的摇树,删除了应用程序中不需要的其他部分。

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

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


至于现在的 Angular 6,供应商仍然是 4MB,仅用于安装 Angular/Material 和 Firebase
这是角度/材料的问题,即使我遇到了这个错误。未正确完成摇树可能是根本原因。使用新的渲染器引擎 IVY 可能会解决。
E
Eric Simonton

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


2/我尝试了上面评论中的“loadash-es”提示。它减少了我的包大小 0.08mb。
这还不算多!你还有什么以旧方式导入 lodash 的吗?除非一切都以新的方式导入,否则您将得不到任何帮助。
我想我已经更换了一切。否则大小不会改变。我在下面给出了另一个提示(gzip 的东西),这对我们很有帮助。
有趣的。 lodash 贡献了多少捆绑包? (例如使用 source-map-explorer。)
通过此导入更改,我们的解压包大小从 1.0MB 减少到 663kB(213.4kB -> 126kB 打包)。我们必须更新应用程序中的每个导入,但这并不困难或耗时。
J
Jacques Cornat

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

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

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

这是我创建的一个存储库 (github.com/JCornat/min-angular),用于测试最小的 Angular 包大小,我获得了 384kB。我相信有简单的方法来优化它。

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


什么特定的 angular-starter 配置有助于减小包大小?是 webpack.config 吗?
是的,正是 webpack 配置减少了包的大小。
R
Renil Babu

以下解决方案假设您使用 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。希望能帮助到你


V
Victor Zakharov

这里的所有答案都已过时。我刚刚使用 Angular 13 CLI 构建了名为“英雄之旅”的 Angular 标准样板应用程序。初始产品构建耗时 10 秒,随后在 3 秒内完成。 Gzip 之前的包大小为 244kB。我用来构建的命令是“ng build”,对样板项目没有任何更改。

关于这个话题有很多错误信息。让我们传播事实。

构建文件夹大小,以字节为单位,按框架,.map 文件被删除,没有 gzip。

更新 2022/03/02:Angular 13.2.5 - 171,580(ng 新的测试应用程序,scss,无路由器)。 JS 大小 153.58kb,压缩后估计为 46,90kb,由 CLI 控制台输出提供。

更新 2022/03/02:Angular 13.2.5 - 249,449(ng 新的 angular-tour-of-heroes、scss、路由器)。 JS 大小 229.49kb,gzip 估计为 64.91kb,由 CLI 提供。

Angular 13.0.0 - 264,563(ng 新的 angular-tour-of-heroes、scss、路由器)。

没有路由器的 React 17.0.2 - 167,074 (npx create-react-app my-app)。

React 17.0.2 with Router - 172,459(npx create-react-app my-app,将 "react-router-dom": "6.0.2" 添加到 package.json,将 包装在 中,如所述这里)。

https://i.stack.imgur.com/93das.png


您能否提供包含路由器的反应产品尺寸的见解?
@DeekshithAnand:我更新了我的答案。只是增加了+5KB。
k
kwalski

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

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

块 {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 kB {4} [初始] [渲染] 块 {1} main.e7496551a26816427b68.bundle.js (main) 2.2 MB {3} [初始] [渲染]块 {2} styles.056656ed596d26ba0192.bundle.css(样式)69 字节 {4} [初始] [渲染] 块 {3} vendor.62c2cfe0ca794a5006d1.bundle.js(供应商)3.84 MB [初始] [渲染] 块 {4 } inline.0b9c3de53405d705e757.bundle.js (inline) 0 bytes [entry] [rendered]

删除 Angular2-moment 并改用 DatePipe 后

块 {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 kB {4} [初始] [渲染] 块 {1} main.f2b62721788695a4655c.bundle.js (main) 2.2 MB {3} [初始] [渲染]块 {2} styles.056656ed596d26ba0192.bundle.css(样式)69 字节 {4} [初始] [渲染] 块 {3} vendor.e1de06303258c58c9d01.bundle.js(供应商)3.35 MB [初始] [渲染] 块 {4 } inline.3ae24861b3637391ba70.bundle.js (inline) 0 bytes [entry] [rendered]

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

即使您已经熟悉外部库,也值得检查 Angular 标准包可以做什么。


S
Stefdelec

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

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


A
AJAY AVHAD

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


C
Community

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

如果我只运行 ng build - 我会得到这些文件:

https://i.stack.imgur.com/PU6IF.png

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

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

https://i.stack.imgur.com/QMVxv.png

文件夹的总大小为 584K。

一个和相同的代码。在这两种情况下,我都启用了 Ivy。角度是 8.2.13。

所以 - 我猜你没有将 --prod 添加到你的构建命令中?


P
Patricio Vargas

如果您使用的是 Angular 8+,并且想要减小包的大小,您可以使用 Ivy。 Ivy 是 Angular 9 中的默认视图引擎,只需转到 src/tsconfig.app.json 并添加 angularCompilerOptions 参数,例如:

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

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

P
Patricio Vargas

在我的情况下,这确实减小了尺寸:

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

对于 Angular 5+ ng-build --prod 默认执行此操作。运行此命令后的大小从 1.7MB 减少到 1.2MB,但不足以满足我的生产目的。

我在 facebook messenger 平台上工作,messenger 应用程序需要小于 1MB 才能在 messenger 平台上运行。一直试图找出有效的摇树解决方案,但仍然没有运气。


请注意此解决方案/评论。出于某种原因,在执行此操作后,大量引用被删除,并对我的项目造成了灾难。
B
Bat0u89

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

默认情况下,定义了生产配置,并且 ng build 命令具有使用此配置构建的 --prod 选项。生产配置设置默认值,以多种方式优化应用程序,例如捆绑文件、最小化多余的空格、删除注释和死代码,以及重写代码以使用简短、神秘的名称(“缩小”)。

此外,您可以使用 @angular-builders/custom-webpack:browser builder 压缩所有可部署文件,其中您的自定义 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;
    ...
}

在我的例子中,dist 文件夹在 ng build 中使用 --prod 后从 25 缩小到 5 mb,然后在压缩后进一步缩小到 1.5 mb。


H
Hiep Tran

更新:2022/05/23,角度 14 (RC1)

g-zipng build --prod 是两个非常有用的解决方案。这会对你有很大帮助。但如果,你做了什么,尽力而为。它仍然不起作用?使用延迟加载模块。还是不行?

这是给你的答案。目前我正在使用 nx 将我的 Angular 13 升级到 Angular 14 项目,我发现“桶副作用”会导致您的 main.js 捆绑包增加。解决方案很简单。

将 tsconfig.json 构建模块从 "module": "commonjs" 更改为 "module": "es2020" 或 esnext(你应该使用 es2020 在这里解释 https://web.archive.org/web/20220605011837/https:// angular.io/guide/migration-update-module-and-target-compiler-options)

https://i.stack.imgur.com/WhTlE.png

将 sideEffects: false 添加到 package.json 并查看结果:

https://i.stack.imgur.com/9m26L.png

为什么?

完整的解释在这里 https://webpack.js.org/guides/tree-shaking/#conclusion 和这里 https://github.com/angular/angular-cli/issues/16799 和这里 https://stackoverflow.com/a/59353152/5748537。但我可以为你简写:

你有模块“A 是小”,而“B 是大”。您将它们写入 UI 库并将它们都导出到 index.ts 文件中。您在项目中导入 A 。最终捆绑包仍然包含您不想要的 B。

为什么?

因为 commonjs 不聪明。使用 es2020 更好,他们知道哪些是有用的,哪些不是。但他们不确定是否应该删除它。您添加 sideEffects: false 告诉他们:“清除死代码是安全的”。他们做到了。那么你的捆绑包很小。这可以在任何现代 JS 框架中使用,包括 React、VueJS

在 Angular 项目中阅读有关桶副作用的问题:https://github.com/angular/angular-cli/issues/16799

p/s:我的生产 Angular 网站在这里:https://awread.vn,每天有 100 个用户。


angular.io 链接是 not found
wew,由于 angular.io 已死,我将其更改为 web.archive.org/web/20220605011837/https://angular.io/guide/…
s
sah1

我有一个 Angular 5 + spring boot 应用程序(application.properties 1.3+),借助压缩(下面附加的链接)能够将 main.bundle.ts 的大小从 2.7 MB 减小到 530 KB。

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

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


a
antidote

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


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅