제품 번들 크기를 줄이는 방법은 무엇입니까?


135

에 의해 초기화 된 간단한 응용 프로그램이 angular-cli있습니다.

3 개의 경로와 관련된 일부 페이지를 표시합니다. 세 가지 구성 요소가 있습니다. 이 페이지 I 사용 중 하나에 lodash일부 데이터를 얻을 수 및 각도 2 HTTP 모듈 (RxJS 사용 Observable들, map그리고 subscribe). 간단한 요소를 사용하여 이러한 요소를 표시합니다 *ngFor.

그러나 내 앱이 정말 간단하다는 사실에도 불구하고 거대한 (내 의견으로는) 번들 패키지 및 맵을 얻습니다. gzip 버전에 대해서는 이야기하지 않지만 gzipping 전 크기입니다. 이 질문은 일반적인 권장 사항 문의입니다.

일부 테스트 결과 :

ng 빌드

해시 : 8efac7d6208adb8641c1 시간 : 10129ms 청크 {0} main.bundle.js, main.bundle.map (메인) 18.7 kB {3} [초기] [렌더링]

청크 {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (스타일) 155 kB {4} [초기] [렌더링]

청크 {2} scripts.bundle.js, scripts.bundle.map (스크립트) 128 kB {4} [초기] [렌더링]

청크 {3} vendor.bundle.js, vendor.bundle.map (공급 업체) 3.96MB [초기] [렌더링]

청크 {4} inline.bundle.js, inline.bundle.map (인라인) 0 바이트 [entry] [렌더링]

대기 : 간단한 앱을위한 10Mb 공급 업체 번들 패키지?

ng 빌드 --prod

해시 : 09a5f095e33b2980e7cc 시간 : 23455ms 청크 {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (메인) 18.3 kB {3} [초기] [렌더링]

청크 {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css, styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.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.96MB [초기] [렌더링]

청크 {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (인라인) 0 바이트 [entry] [렌더링]

다시 기다립니다 : prod와 비슷한 공급 업체 번들 크기?

ng build --prod --aot

해시 : 517e4425ff872bbe3e5b 시간 : 22856ms 청크 {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (main) 130 kB {3} [초기] [렌더링]

청크 {1} 스타일 .e53a388ae1dd2b7f5434.bundle.css, 스타일 .e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (스타일) 154 kB {4} [초기] [렌더링]

청크 {2} 스크립트 .e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (스크립트) 128 kB {4} [초기] [렌더링]

청크 {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map (공급 업체) 2.75MB [초기] [렌더링]

청크 {4} 인라인 .97c0403c57a46c6a7920.bundle.js, 인라인 .97c0403c57a46c6a7920.bundle.map (인라인) 0 바이트 [항목] [렌더링]

ng build --aot

해시 : 040cc91df4df5ffc3c3f 시간 : 11011ms 청크 {0} main.bundle.js, main.bundle.map (메인) 130kB {3} [초기] [렌더링]

청크 {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (스타일) 155 kB {4} [초기] [렌더링]

청크 {2} scripts.bundle.js, scripts.bundle.map (스크립트) 128 kB {4} [초기] [렌더링]

청크 {3} vendor.bundle.js, vendor.bundle.map (공급 업체) 2.75MB [초기] [렌더링]

청크 {4} inline.bundle.js, inline.bundle.map (인라인) 0 바이트 [entry] [렌더링]

prod에 내 앱을 배포하기위한 몇 가지 질문이 있습니다.

  • 공급 업체 번들이 왜 그렇게 큰가요?
  • 나무 흔들림이 올바르게 사용 angular-cli됩니까?
  • 이 번들 크기를 개선하는 방법은 무엇입니까?
  • .map 파일이 필요합니까?
  • 테스트 기능이 번들에 포함되어 있습니까? 나는 그것들을 자극 할 필요가 없다.
  • 일반적인 질문 : 제품을 포장하기 위해 권장되는 도구는 무엇입니까? 어쩌면 angular-cli(백그라운드에서 Webpack을 사용하는) 최선의 선택이 아닐까요? 더 잘할 수 있을까요?

Stack Overflow에 대한 많은 토론을 검색했지만 일반적인 질문을 찾지 못했습니다.


각도 2 앱 최적화에 대한 자세한 내용은 github.com/mgechev/angular-performance-checklist#introduction
Timathon

1
그러나 나는 우리가 많은 각도의 진료소가 진화하고 상황이 더 좋고 나아질 것이라고 걱정하지 않는다고 생각합니다. angular-cli에없는 기능이 필요한 경우 해당 리포지토리에
Timathon

@Timathon은 어떤면에서 옳다고 생각하지만 누군가 Angular2를 프로덕션에 배포하려고 시도하는 경우 번들 크기에 관심 을 가져야 합니다. 이는 앱 성능에 직접적인 영향을 미칩니다. 각도 성능 점검표는 개선 할 수있는 것을 확인할 수있는 훌륭한 리소스입니다. 각진 팀은 번들 크기를 줄이기 위해 노력하고 있습니다. 그것이 어디로 가는지보고 흥분했습니다!
Jack Clancy

답변:


72

2020 년 2 월 업데이트

이 답변은 많은 견인력을 얻었으므로 새로운 각도 최적화로 업데이트하는 것이 가장 좋을 것이라고 생각했습니다.

  1. 다른 답변자가 말했듯 ng build --prod --build-optimizer이 Angular v5 미만을 사용하는 사람들에게 좋은 옵션입니다. 최신 버전의 경우 기본적으로이 작업이 수행됩니다.ng build --prod
  2. 또 다른 옵션은 모듈 청킹 / 지연 로딩을 사용하여 애플리케이션을 더 작은 청크로 분할하는 것입니다.
  3. 아이비 렌더링 엔진은 기본적으로 Angular 9에서 제공되며 더 나은 번들 크기를 제공합니다.
  4. 타사 뎁이 나무를 흔들 수 있는지 확인하십시오. 아직 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 & Tree Shaking (각도 cli는 즉시 사용 가능). Angular 9를 사용하면 기본적으로 prod 및 dev 환경에서 AOT가 사용됩니다.

2) Angular Universal AKA 서버 측 렌더링 사용 (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


내 최소한의 프로젝트는 참조 384KB입니다 github.com/JCornat/min-angular 내가 확인을 최적화 할 수있는 쉬운 방법이 있지만, 250KB에 가까운!
Jacques Cornat 2016 년

2
@JacquesCornat는 좋아 보인다! 그러나 앱에는 단일 구성 요소 만 있습니다. 문제는 번들 크기 또는 더 큰 애플리케이션을 관리하는 방법입니다. 종종 AOT는 번들 크기를 충분히 줄이지 않으며 사람들은 다른 방법으로 최적화해야합니다. 모든 사람들이 webpack-bundle-analyzer를 확인하는 것이 좋습니다. 팽창을 일으키는 원인을 확인하는 매우 유용하고 쉬운 방법
Jack Clancy

불행히도, 같은 유틸리티 sw-precache는 2MB보다 큰 공급 업체 번들을 처리하지 않습니다.

1
@JackClancy "문제는 번들 크기 또는 더 큰 애플리케이션을 관리하는 방법입니다." 그의 질문은 "이 묶음 크기를 개선하는 방법"입니까? 그는 3 가지 구성 요소를 가진 그의 최소한의 앱에 대해 이야기하고 있습니다. 어쨌든 큰 번들에 대해 이야기하면서 AngularClass / angular-starter 구성을 사용하여 리포지토리에서와 마찬가지로 큰 앱의 번들 크기는 8MB (지도 파일이없는 4MB)에서 580kB로 증가했습니다.
Jacques Cornat

1
고마워요, 당신은 저를 구했습니다. --prod는 앱 크기를 6Mb에서 1.2Mb로 줄였습니다. 여전히 완벽하지는 않지만 데스크탑 전용이기 때문에 받아들입니다.
Vyacheslav Tsivina

21

최신 앵귤러 클리 버전을 사용하고 ng build --prod --build-optimizer 명령을 사용하십시오 . prod env의 빌드 크기를 확실히 입니다.

이것이 바로 빌드 최적화 프로그램이 수행하는 작업입니다.

빌드 최적화 프로그램에는 두 가지 주요 작업이 있습니다. 먼저, 애플리케이션의 일부를 순수한 것으로 표시 할 수 있으므로 기존 도구에서 제공하는 트리 흔들림이 개선되어 필요하지 않은 애플리케이션의 추가 부분이 제거됩니다.

빌드 최적화 프로그램이 수행하는 두 번째 작업은 응용 프로그램 런타임 코드에서 Angular 데코레이터를 제거하는 것입니다. 데코레이터는 컴파일러에서 사용하며 런타임에는 필요하지 않으며 제거 할 수 있습니다. 이러한 각 작업은 JavaScript 번들의 크기를 줄이고 사용자의 응용 프로그램 부팅 속도를 높입니다.

참고 : Angular 5 이상에 대한 하나의 업데이트 ng build --prod로 위의 프로세스를 자동으로 처리합니다. :)


1
앵귤러 6의 경우 공급 업체는 여전히 앵귤러 / 재료 및
파이어베이스

그것은 각도 / 재질의 문제입니다. 심지어 그 오류에 직면했습니다. 나무 흔들림이 올바르게 수행되지 않았을 수 있습니다. 새로운 렌더러 엔진 IVY로 아마 해결 될 것입니다.
Shubhendu Vaid

13

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에서 작동하는지 확인하려면 여기를 확인하십시오.


1
2 / 위의 의견에서 "loadash-es"팁을 시도했습니다. 내 번들 크기를 0.08mb 줄입니다.
Stefdelec

그다지 중요하지 않습니다! 여전히 오래된 방식으로 lodash를 가져 오는 다른 것이 있습니까? 모든 것을 새로운 방식으로 가져 오지 않으면 도움을받을 수 없습니다 .
Eric Simonton

나는 모든 것을 대체했다고 생각합니다. 그렇지 않으면 크기가 변경되지 않았을 것입니다. 나는 우리에게 정말로 도움이되는 또 다른 팁 (gzip 일)을주었습니다.
Stefdelec

흥미 롭군 얼마나 많은 번들이 기여하고 있었습니까? (예 : source-map-explorer.)
Eric Simonton

11

첫째, Angular 2는 많은 라이브러리에 의존하기 때문에 공급 업체 번들은 엄청납니다. Angular 2 앱의 최소 크기 는 약 500KB입니다 (일부 경우 250KB, 하단 게시물 참조).
에 의해 나무 흔들림이 올바르게 사용됩니다 angular-cli.
마십시오 하지 포함 .map디버깅에만 사용하기 때문에, 파일을. 또한 핫 교체 모듈을 사용하는 경우 제거하여 공급 업체를 가볍게하십시오.

프로덕션을 위해 포장하기 위해 실제로 최적화 또는 디버깅을 위해 Webpack을 사용합니다 (그리고 angular-cli도 의존합니다 ) configure everything.
을 사용하고 싶다면 Webpack첫 번째보기가 약간 까다 롭다는 데 동의하지만 그물에 대한 자습서를 보면 실망하지 않을 것입니다.
그렇지 않으면를 사용 angular-cli하십시오.이 작업을 실제로 잘 수행하십시오.

사용 AOT 컴파일하는 최적화 애플리케이션에 필수이며,에 각도 2 응용 프로그램을 축소 250킬로바이트 .

최소 Angular 번들 크기를 테스트하기 위해 만든 리포지토리 ( github.com/JCornat/min-angular )는 384kB 입니다. 그것을 최적화하는 쉬운 방법이 있다고 확신합니다.

위의 레포지토리 에서와 마찬가지로 AngularClass / angular-starter 구성을 사용하여 큰 응용 프로그램에 대해 이야기 하면 큰 응용 프로그램 ( 150 + 구성 요소 )의 내 번들 크기 는 8MB (지도 파일이없는 4MB)에서 580kB변경되었습니다 .


번들 크기를 줄이는 데 도움이되는 특정 각도 스타터 구성은 무엇입니까? webpack.config입니까?
MartinJH

2
예, 번들 크기를 줄이는 것은 웹팩 구성입니다.
Jacques Cornat

설명을 주셔서 감사합니다 :)
MartinJH

8

다음 솔루션은 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 (약)를 줄이십시오. 아래 프로세스를 따르십시오.

폴더 vendor내부 src와 공급 업체 폴더 내부에 폴더를 작성하고 파일을 작성 rxjs.ts 하고 아래 코드를 붙여 넣으십시오.

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

그런 다음 tsconfig.jsonangular-cli 응용 프로그램 의 파일에 다음 내용을 추가하십시오 . 그런 다음에 compilerOptions다음 json을 추가하십시오.

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

이렇게하면 빌드 크기가 너무 작아집니다. 내 프로젝트에서 크기를 11mb에서 1mb로 줄였습니다. 그것이 도움이되기를 바랍니다.


5

내가 공유하고 싶은 한 가지는 가져온 라이브러리가 dist의 크기를 늘리는 방법입니다. angular2-moment 패키지를 가져 왔지만 @ angular / common에서 내 보낸 표준 DatePipe를 사용하여 필요한 모든 날짜 시간 형식을 지정할 수있었습니다.

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

청크 {0} polyfills.036982dc15bb5fc67cb8.bundle.js (폴리 필) 191 kB {4} [초기] [렌더링] 청크 {1} main.e7496551a26816427b68.bundle.js (메인) 2.2 MB {3} [초기] [렌더링] 청크 {2} 스타일 .056656ed596d26ba0192.bundle.css (스타일) 69 바이트 {4} [초기] [렌더링] 청크 {3} 공급 업체 .62c2cfe0ca794a5006d1.bundle.js (공급 업체) 3.84MB [초기] [렌더링] 청크 {4 } inline.0b9c3de53405d705e757.bundle.js (인라인) 0 바이트 [entry] [렌더링]

Angular2-moment를 제거하고 대신 DatePipe를 사용한 후

청크 {0} polyfills.036982dc15bb5fc67cb8.bundle.js (폴리 필) 191 kB {4} [초기] [렌더링] 청크 {1} main.f2b62721788695a4655c.bundle.js (메인) 2.2 MB {3} [초기] [렌더링] 청크 {2} 스타일 .056656ed596d26ba0192.bundle.css (스타일) 69 바이트 {4} [초기] [렌더링] 청크 {3} 공급 업체 .e1de06303258c58c9d01.bundle.js (공급 업체) 3.35MB [초기] [렌더링] 청크 {4 } inline.3ae24861b3637391ba70.bundle.js (인라인) 0 바이트 [항목] [렌더링]

공급 업체 번들이 메가 바이트의 절반 을 줄였습니다 .

요점은 이미 외부 라이브러리에 익숙하더라도 각도 표준 패키지가 무엇을 할 수 있는지 확인하는 것이 좋습니다.



1

당신이 실행 한 경우 ng build --prod-당신은 전혀 vendor파일 이 없어야 합니다.

방금 실행 ng build하면 다음 파일이 생성됩니다.

여기에 이미지 설명을 입력하십시오

폴더의 총 크기는 ~ 14MB입니다. 화이팅! :디

그러나 내가 실행하면 ng build --prod-다음 파일을 얻습니다.

여기에 이미지 설명을 입력하십시오

폴더의 총 크기는 584K입니다.

하나의 동일한 코드. 두 경우 모두 아이비를 활성화했습니다. 각도는 8.2.13입니다.

그래서-당신이 --prod당신의 빌드 명령에 추가하지 않았다고 생각 합니까?


1

Angular 8 이상을 사용하고 번들 크기를 줄이려면 Ivy를 사용할 수 있습니다. Ivy는 Angular 9의 기본 뷰 엔진으로 제공됩니다. src / tsconfig.app.json으로 이동하여 angularCompilerOptions 매개 변수를 추가하십시오.

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

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

1

이것은 내 경우에는 크기를 줄였습니다.

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

Angular 5+ ng-build --prod의 경우 기본적으로이 작업을 수행합니다. 이 명령을 실행 한 후 크기가 1.7MB에서 1.2MB로 줄었지만 프로덕션 용도로는 충분하지 않습니다.

나는 페이스 북 메신저 플랫폼에서 작업하고 메신저 플랫폼에서 실행하려면 메신저 앱이 1MB 미만이어야합니다. 효과적인 나무 흔들림에 대한 해결책을 찾으려고 노력했지만 여전히 운이 없습니다.



0

압축 (아래 첨부 된 링크)의 도움으로 각도 5 + 스프링 부트 응용 프로그램 (application.properties 1.3 +)이 있는데 main.bundle.ts 크기를 2.7MB에서 530KB로 줄일 수있었습니다.

또한 기본적으로 --aot 및 --build-optimizer는 --prod 모드를 사용하여 활성화되며 별도로 지정할 필요가 없습니다.

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


0

ng build --prod에 대해 "production"이라는 구성이 있는지 확인하십시오. ng build --configuration = production의 약어 이므로 문제가 화면 바로 앞에 있기 때문에 문제가 해결되지 않았습니다. 나는 이것이 일반적이라고 생각합니다 ... i18n을 사용하여 모든 구성의 이름을 프로덕션 엔으로 변경하여 앱을 국제화했습니다. 그런 다음 기본 최적화가 사용되며 최적에 가까워 야한다고 가정하고 ng build --prod로 빌드했지만 실제로 ng 빌드가 실행되어 250kb 대신 7mb 번들이 발생했습니다.


0

각도 문서 v9에서 가져온 것 ( https://angular.io/guide/workspace-config#alternate-build-configurations ) :

기본적으로 프로덕션 구성이 정의되고 ng build 명령에는이 구성을 사용하여 빌드하는 --prod 옵션이 있습니다. 프로덕션 구성은 파일 번들링 , 과도한 공백 최소화 , 주석 및 데드 코드 제거 , 짧은 암호 이름 ( " 최소화 " ) 을 사용하도록 코드 다시 작성 같은 여러 가지 방법으로 앱을 최적화하는 기본값을 설정합니다 .

또한 사용자 정의 webpack.config.js가 다음과 같은 @ angular-builders / custom-webpack : browser 빌더를 사용하여 모든 배치 가능 파일을 압축 할 수 있습니다.

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

그런 다음 압축 된 컨텐츠를 제공하도록 웹 서버를 구성해야합니다 (예 : 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 폴더는 빌드에서 --prod를 사용한 후 25MB에서 5MB로 줄어들었다가 압축 후 1.5MB로 줄었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.