Як зменшити розмір продуктового пакета?


135

У мене є проста програма, ініціалізована користувачем angular-cli.

Він відображає деякі сторінки відносно 3 маршрутів. У мене є 3 компоненти. На одній із цієї сторінки я використовую lodashта HTTP модулі Angular 2 для отримання деяких даних (використовуючи RxJS Observables mapта subscribe). Я показую ці елементи за допомогою простого *ngFor.

Але, незважаючи на те, що моя програма дійсно проста, я отримую величезний (на мій погляд) пакет пакетів і карт. Я не говорю про версії gzip, але розмір до gzipping. Це питання є лише загальним запитом щодо рекомендацій.

Деякі результати тестів:

ng build

Хеш: 8efac7d6208adb8641c1 Час: 10129 мс шматок {0} main.bundle.js, main.bundle.map (основний) 18,7 кБ {3} [початковий] [надано]

фрагмент {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (стилі) 155 kB {4} [початковий] [викладено]

фрагмент {2} scriptpts.bundle.js, scriptpts.bundle.map (сценарії) 128 кБ {4} [початковий] [надано]

шматок {3} vendor.bundle.js, vendor.bundle.map (постачальник) 3,96 Мб [початковий] [надано]

фрагмент {4} inline.bundle.js, inline.bundle.map (inline) 0 байт [запис] [надано]

Зачекайте: пакет пакетів постачальників 10 Мб для такого простого додатка?

ng build --prod

Хеш: 09a5f095e33b2980e7cc Час: 23455ms шматок {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (основний) 18,3 кБ {3} [початковий] [надано]

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

chunk {2} scriptpts.c5b720a078e5464ec211.bundle.js, scriptpts.c5b720a078e5464ec211.bundle.map (сценарії) 128 kB {4} [початковий] [надано]

шматок {3} vendor.07af2467307e17d85438.bundle.js, vendor.07af2467307e17d85438.bundle.map (постачальник) 3,96 Мб [початковий] [надано]

фрагмент {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (вбудований) 0 байт [запис] [надано]

Зачекайте знову: такий подібний розмір пакета постачальників для prod?

ng build --prod --aot

Хеш: 517e4425ff872bbe3e5b Час: 22856ms шматок {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (основний) 130 кБ {3} [початковий] [надано]

chunk {1} styles.e53a388ae1dd2b7f5434.bundle.css, styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (styles) 154 kB {4} [початковий] [render]

шматок {2} скриптів.e5c2c90547f3168a7564.bundle.js, скрипти.e5c2c90547f3168a7564.bundle.map (сценарії) 128 кБ {4} [початковий] [надано]

фрагмент {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map (постачальник) 2,75 Мб [початковий] [надано]

фрагмент {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map (вбудований) 0 байт [запис] [надано]

ng build --aot

Хеш: 040cc91df4df5ffc3c3f Час: 11011ms фрагмент {0} main.bundle.js, main.bundle.map (main) 130 кБ {3} [початковий] [виведено]

фрагмент {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (стилі) 155 kB {4} [початковий] [викладено]

фрагмент {2} scriptpts.bundle.js, scriptpts.bundle.map (сценарії) 128 кБ {4} [початковий] [надано]

шматок {3} vendor.bundle.js, vendor.bundle.map (постачальник) 2,75 Мб [початковий] [надано]

фрагмент {4} inline.bundle.js, inline.bundle.map (inline) 0 байт [запис] [надано]

Отож кілька запитань щодо розгортання мого додатка в prod:

  • Чому пакети постачальників такі величезні?
  • Чи правильно використовується тремтіння дерева angular-cli?
  • Як поліпшити розмір цього пакета?
  • Чи потрібні файли .map?
  • Чи включаються функції тестування в пакети? Мені вони не потрібні у продажі.
  • Загальне запитання: які рекомендовані інструменти упакувати для продукту? Можливо angular-cli(використання Webpack у фоновому режимі) не найкращий варіант? Чи можемо ми зробити краще?

Я шукав багато дискусій щодо Stack Overflow, але не знайшов жодного загального питання.


Щоб дізнатися більше про кутову оптимізацію додатків, перегляньте це: github.com/mgechev/angular-performance-checklist#introduction
Timathon

1
Але я не думаю, що нам слід було б турбуватися про те, щоб розвиватись кутові кліпи, і все буде робити все краще і краще. Якщо вам потрібна функція, якої у кутових кліпів немає, просто надішліть випуск у їхньому репортажі
Timathon

хоча я думаю, що @Timathon в деякому відношенні має рацію, якщо хтось намагається розгорнути Angular2 у виробництві, він повинен дбати про розміри пакетів, оскільки це безпосередньо впливає на продуктивність програми. Контрольний список кутових характеристик - це чудовий ресурс, щоб побачити, що можна покращити. кутова команда працює над зменшенням розмірів пучка. Раді бачити, куди це іде!
Джек Клансі

Відповіді:


72

Оновлення лютого 2020 року

Оскільки ця відповідь отримала велику тягу, я вважав, що найкраще буде оновити її новішими кутовими оптимізаціями:

  1. Як сказав інший відповідь, ng build --prod --build-optimizerце хороший варіант для людей, які використовують менше, ніж Angular v5. Для нових версій це робиться за замовчуванням за допомогоюng build --prod
  2. Іншим варіантом є використання модульного блокування / ледачого завантаження, щоб краще розділити додаток на менші шматки
  3. Плющ-рендерінг за замовчуванням поставляється в Angular 9, він пропонує кращі розміри в комплекті
  4. Переконайтеся, що ваші сторонні депи можуть бути зруйнованими по дереву. Якщо ви ще не використовуєте Rxjs v6, вам слід.
  5. Якщо все інше не вдається, скористайтеся інструментом на зразок webpack-bundle-аналізатора, щоб побачити, що спричиняє здуття у ваших модулях
  6. Перевірте, чи зберігаються файли

Деякі твердження, що використання компіляції AOT може зменшити розмір пакета постачальника до 250 кбіт. Однак у прикладі BlackHoleGalaxy він використовує компіляцію AOT і все ще залишається з розміром пакета постачальника в 2,75 Мб ng build --prod --aot, на 10 разів більше, ніж передбачається, 250 Кбіт. Це не є нормою для angular2 додатків, навіть якщо ви використовуєте v4.0. 2,75 Мб все ще занадто великий для тих, хто дійсно дбає про продуктивність, особливо на мобільному пристрої.

Ви можете зробити кілька речей, щоб допомогти виконувати свою програму:

1) AOT & Tree Shaking (кутовий затискач робить це поза коробкою). У режимі Angular 9 AOT за замовчуванням використовується середовище prod та dev.

2) Використання кутового універсального візуалізації на сервері AKA (не в кліпі)

3) Веб-робітники (знову ж таки, не в кліпі, але дуже запитувана функція)
див: https://github.com/angular/angular-cli/isissue/2305

4) Сервісні працівники
див: https://github.com/angular/angular-cli/isissue/4006

Можливо, вам не знадобиться все це в одній програмі, але це деякі з варіантів, які зараз є для оптимізації кутових характеристик. Я вірю / сподіваюся, що Google знає про нестабільні недоліки в плані продуктивності та планує покращити це в майбутньому.

Ось посилання, яке більш глибоко розповідає про деякі згаданих нами концепцій:

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


Мій мінімальний проект становить 384 кб, див. Github.com/JCornat/min-angular Я впевнений, що існує простий спосіб його оптимізації, але він близький до 250 кБ!
Жак Корнат

2
@JacquesCornat виглядає добре! Але ваш додаток має лише один компонент. Питання полягає в тому, як керувати розмірами пакету чи більшими додатками. Часто AOT недостатньо зменшує розміри пакету, і люди змушені шукати інший спосіб оптимізації. Я настійно рекомендую всім перевірити webpack-bundle-аналізатор. Дуже корисний / простий спосіб побачити, що спричиняє набряк
Джек Клансі

На жаль, утиліти, такі як sw-precacheвідмовляються мати справу з пакетами постачальників, більшими за 2 Мб.

1
@JackClancy "Питання в тому, як керувати розмірами пакету чи більшими програмами". У нього немає запитання: "як поліпшити розмір цього пакета?" і він говорить про своє мінімальне додаток з 3 компонентами. У будь-якому разі, якщо говорити про великі розшарування, використовуючи конфігурацію AngularClass / angular-starter, таку ж, як і в моїй репо, розмір пакету для великих додатків перейшов від 8 МБ (4 МБ без файлів карт) до 580 КБ.
Жак Корнат

1
Спасибі, ти врятував мене. --prod зменшив розмір програми з 6Mb до 1,2Mb. Все ще не ідеально, але прийнятний, оскільки він призначений лише для настільного використання.
В’ячеслав Цівіна

21

Використовуйте останню кутову версію cli та використовуйте команду ng build --prod --build-optimizer Це, безумовно, зменшить розмір збірки для prod env.

Ось що робить оптимізатор збірки під кришкою:

Оптимізатор збірки має два основні завдання. По-перше, ми можемо позначити частини вашої програми як чисті, це покращує тремтіння дерева, що надається наявними інструментами, видаляючи додаткові частини вашої програми, які не потрібні.

Друге, що робить оптимізатор збірки - видалити кутові декоратори з коду виконання програми. Декоратори використовуються компілятором, вони не потрібні під час виконання, і їх можна видалити. Кожне з цих завдань зменшує розмір ваших пакетів JavaScript і збільшує швидкість завантаження програми для ваших користувачів.

Примітка . Одне оновлення для версії Angular 5 і вище, ng build --prodавтоматично піклуйтеся про вищезгаданий процес :)


1
Що стосується кутових 6 зараз, то постачальник поки що становить 4 МБ, лише для встановлення кутових / матеріалів та вогневих баз
FindOutIslamNow

Це проблема з кутовим / матеріалом, навіть я зіткнувся з цією помилкою. Тремтіння дерев, зроблене неправильно, ймовірно, є першопричиною. З новим двигуном рендерінга 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у ваш пакет. Тому я будував колекцію спрощених функцій лодашу. Моя реалізація flattenсприяє 50 bytes. Ви можете перевірити це, щоб перевірити, чи працює він для вас: https://github.com/simontonsoftware/micro-dash


1
2 / Я спробував поради "loadash-es" з коментаря вище. Це зменшує розмір моєї пачки на 0,08 Мб.
Стефделек

Це не багато! У вас ще є щось, що імпортує лодаш по-старому? Ви не отримаєте допомоги, якщо все не буде імпортовано по-новому.
Ерік Сімонтон

Я думаю, що я все замінив. Інакше розмір не змінився б. Я дав ще одну пораду внизу (gzip thing), яка нас справді допомогла.
Стефделек

Цікаво. Скільки вашого пакету вклав / вдавав квартир? (Наприклад, використовуючи source-map-explorer.)
Ерік Сімонтон,

11

По-перше, пакети постачальників величезні просто тому, що Angular 2 покладається на безліч бібліотек. Мінімальний розмір додатка Angular 2 становить близько 500 КБ (у деяких випадках 250 КБ див. Нижній пост).
Дерево струшування правильно використовується angular-cli.
Ви НЕ включати .mapфайли, тому що використовується тільки для налагодження. Крім того, якщо ви використовуєте модуль гарячої заміни, видаліть його, щоб полегшити постачальника.

Для упаковки для виробництва я особисто використовую Webpackна нього також покладається angular-cli ), тому що ви дійсно можете configure everythingоптимізувати або налагодити.
Якщо ви хочете використовувати Webpack, я згоден, що перший погляд трохи складний, але дивіться підручники в мережі, ви не розчаруєтесь.
Інакше, використовуйте angular-cli, які дуже добре виконують роботу.

Використання заздалегідь компіляції є обов'язковим для оптимізації програм та зменшення програми Angular 2 до 250 КБ .

Ось репортаж, який я створив ( github.com/JCornat/min-angular ), щоб перевірити мінімальний кутовий розмір пучка, і я отримав 384 кБ . Я впевнений, що існує простий спосіб її оптимізувати.

Якщо говорити про великі програми, використовуючи конфігурацію AngularClass / angular-starter , таку ж, як у репортажі вище, мій розмір пакету для великих додатків ( 150+ компонентів ) перейшов від 8 МБ (4 МБ без файлів карт) до 580 КБ .


Яка конкретна конфігурація кутового стартера допомагає зменшити розмір пакета? Це webpack.config?
MartinJH

2
Так, саме конфігурація веб-пакету зменшує розмір пакету.
Жак Корнат

Дякую за роз’яснення :)
MartinJH

8

Наступне рішення передбачає, що ви обслуговуєте dist / папку за допомогою nodejs. Будь ласка, використовуйте наступний 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

Якщо ви хочете додатково стиснути збірку, скажіть, зменшити 300 кбіт (прибл.) Від, виконайте наведений нижче процес;

Створіть папку, яку називають vendorвсередині srcпапки, а всередині папки постачальника створіть файл rxjs.ts і вставте в нього код нижче;

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

А потім додайте наступні tsconfig.jsonфайли у файл у програмі angular-cli. Потім у compilerOptions, додайте наступний json;

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

Це зробить ваш розмір збірки занадто маленьким. У своєму проекті я зменшив розмір з 11mb до 1mb. Сподіваюся, це допомагає


5

Я хочу поділитися тим, як імпортні бібліотеки збільшують розмір каналу. У мене був імпортований пакунок angular2-moment, тоді як я міг виконувати потрібне форматування часу, використовуючи стандартний DatePipe, експортований з @ angular / common.

З Angular2-Момент "angular2-moment": "^1.6.0",

шматок {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 кБ {4} [початковий] [наданий] шматок {1} main.e7496551a26816427b68.bundle.js (основний) 2,2 МБ {3} [початковий] [надано] шматок {2} стилів.056656ed596d26ba0192.bundle.css (стилі) 69 байт {4} [початковий] [надано] шматок {3} постачальник.62c2cfe0ca794a5006d1.bundle.js (постачальник) 3,84 МБ [початковий] [відредагований] шматок {4 } inline.0b9c3de53405d705e757.bundle.js (inline) 0 байт [запис] [надано]

Після видалення Angular2-моменту та використання DatePipe замість цього

шматок {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 кБ {4} [початковий] [наданий] шматок {1} main.f2b62721788695a4655c.bundle.js (головний) 2,2 МБ {3} [початковий] [рендерін] шматок {2} стилів.056656ed596d26ba0192.bundle.css (стилі) 69 байт {4} [початковий] [надано] шматок {3} vendor.e1de06303258c58c9d01.bundle.js (постачальник) 3,35 МБ [початковий] [відредагований] шматок {4 } inline.3ae24861b3637391ba70.bundle.js (inline) 0 байт [запис] [надано]

Зауважте, що пакет постачальників зменшив половину Мегабайт!

Справа в тому, що варто перевірити, що можуть робити стандартні кутові пакети, навіть якщо ви вже знайомі із зовнішньою лінзою.



1

Якщо ви запустили ng build --prod- у вас взагалі не повинно бути vendorфайлів.

Якщо я запускаю просто ng build- я отримую ці файли:

введіть тут опис зображення

Загальний розмір папки становить ~ 14 Мб. Ват! : D

Але якщо я запускаю 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,7 Мб до 1,2 МБ, але недостатньо для моєї виробничої мети.

Я працюю на платформі месенджера facebook, а додатки месенджера повинні бути менше 1 МБ, щоб працювати на платформі месенджера. Намагалися знайти рішення для ефективного струшування дерева, але все одно не пощастило.


1

Його робота працює на 100% build збірці --prod --aot - build-optimizer --vendor-chunk = true


0

У мене кутовий додаток для завантаження 5 + (application.properties 1.3+) за допомогою стиснення (посилання додається нижче) зміг зменшити розмір main.bundle.ts розміром з 2,7 МБ до 530 КБ.

Також за замовчуванням увімкнено --aot і --build-optimizer в режимі --prod, їх не потрібно вказувати окремо.

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


0

Перевірте, чи є у вас конфігурація "виробництво" для ng build --prod, оскільки це скорочення для ng build --configuration = виробництво моєї проблеми не вирішено, оскільки проблема сиділа прямо перед екраном. Я думаю, що це може бути досить поширеним ... Я інтернаціоналізував додаток з i18n, перейменувавши всі конфігурації на напр. Production-en. Тоді я побудував за допомогою ng build - prod припускаючи, що оптимізація за замовчуванням використовується і повинна бути близькою до оптимальної, але насправді просто ng build було виконано, в результаті чого пакет 7mb замість 250kb.


0

Взяті з кутових документів v9 ( https://angular.io/guide/workspace-config#alternate-build-configurations ):

За замовчуванням визначена конфігурація виробництва, і команда ng build має опцію --prod, яка будується за допомогою цієї конфігурації. Виробнича конфігурація встановлює параметри за замовчуванням, які оптимізують додаток різними способами, наприклад, згрупування файлів , мінімізація зайвого пробілу , видалення коментарів та мертвого коду та перезапис коду для використання коротких криптовалютних імен ( "мінімізація" ).

Крім того, ви можете стиснути всі ваші розгортання за допомогою @ angular-builders / custom-webpack: конструктор веб-переглядачів, де виглядає ваш власний webpack.config.js:

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 скоротилася від 25 до 5 Мб після просто використання --prod в ng build, а потім зменшилася до 1,5 Мб після стиснення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.