Как уменьшить размер пакета?

135

У меня есть простое приложение, инициализированное angular-cli.

Он отображает несколько страниц, относящихся к 3 маршрутам. У меня 3 компонента. На одной из этих страниц я использую lodashмодули HTTP и Angular 2 для получения некоторых данных (используя RxJS Observables mapи subscribe). Я отображаю эти элементы с помощью простого файла *ngFor.

Но, несмотря на то, что мое приложение действительно простое, я получаю огромный (на мой взгляд) пакет и карты. Я говорю не о версиях gzip, а о размере перед сжатием. Этот вопрос является всего лишь запросом общих рекомендаций.

Некоторые результаты тестов:

нг построить

Хеш: 8efac7d6208adb8641c1 Время: 10129 мс фрагмент {0} main.bundle.js, main.bundle.map (основной) 18,7 КБ {3} [начальный] [обработанный]

фрагмент {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (стили) 155 КБ {4} [начальный] [обработанный]

фрагмент {2} scripts.bundle.js, scripts.bundle.map (скрипты) 128 КБ {4} [начальный] [обработанный]

фрагмент {3} vendor.bundle.js, vendor.bundle.map (vendor) 3,96 МБ [начальный] [обработанный]

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

Подождите: 10- мегабайтный пакет от поставщика для такого простого приложения?

ng build --prod

Хеш: 09a5f095e33b2980e7cc Время: 23455 мс фрагмент {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (main) 18,3 КБ {3} [начальный] [визуализировано]

фрагмент {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css, styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.bfdaa4d8a4eb2d0cb019.bundle.map (стили) начальный 154 КБ [обработано}

фрагмент {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.bundle.map (скрипты) 128 КБ {4} [начальный] [визуализированный]

фрагмент {3} vendor.07af2467307e17d85438.bundle.js, vendor.07af2467307e17d85438.bundle.map (vendor) 3,96 МБ [начальный] [обработанный]

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

Подождите еще раз: такой же размер пакета у производителя для prod?

ng build --prod --aot

Хеш: 517e4425ff872bbe3e5b Время: 22856 мс фрагмент {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (main) 130 КБ {3} [начальный] [визуализировано]

фрагмент {1} styles.e53a388ae1dd2b7f5434.bundle.css, styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (стили) 154 КБ {4} [начальный] [визуализированный]

фрагмент {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (скрипты) 128 КБ {4} [начальный] [обработанный]

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

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

ng build --aot

Хеш: 040cc91df4df5ffc3c3f Время: 11011 мс фрагмент {0} main.bundle.js, main.bundle.map (основной) 130 КБ {3} [начальный] [обработанный]

фрагмент {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (стили) 155 КБ {4} [начальный] [обработанный]

фрагмент {2} scripts.bundle.js, scripts.bundle.map (скрипты) 128 КБ {4} [начальный] [обработанный]

фрагмент {3} vendor.bundle.js, vendor.bundle.map (vendor) 2,75 МБ [начальный] [обработанный]

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

Итак, несколько вопросов по развертыванию моего приложения на продукте:

  • Почему пакеты поставщиков такие огромные?
  • Правильно ли используется дрожание дерева angular-cli?
  • Как улучшить размер этого пакета?
  • Требуются ли файлы .map?
  • Включены ли в комплекты функции тестирования? Мне они не нужны в прод.
  • Общий вопрос: какие инструменты рекомендуются для использования в продуктах? Может быть angular-cli(использование Webpack в фоновом режиме) не лучший вариант? Можем ли мы сделать лучше?

Я просмотрел много обсуждений по Stack Overflow, но не нашел ни одного общего вопроса.

BlackHoleGalaxy
источник
Чтобы узнать больше об оптимизации приложений angular 2, ознакомьтесь с этим: github.com/mgechev/angular-performance-checklist#introduction
Timathon
1
Но я не думаю, что мы должны так сильно волноваться, angular-cli будет развиваться, и все будет делаться все лучше и лучше. Если вам нужна какая-то функция, которой нет в angular-cli, просто отправьте проблему в их репо: github.com/angular/angular-cli
Timathon
хотя я думаю, что @Timathon в некотором смысле прав, если кто-то пытается развернуть Angular2 в производственной среде, он должен заботиться о размерах пакетов, поскольку это напрямую влияет на производительность приложения. Контрольный список производительности angular - отличный ресурс, чтобы увидеть, что можно улучшить. команда angular работает над уменьшением размеров пакетов. Рад видеть, куда он идет!
Джек Клэнси,

Ответы:

73

Обновление февраль 2020 г.

Поскольку этот ответ получил большую поддержку, я подумал, что было бы лучше обновить его новыми оптимизациями Angular:

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

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

Есть несколько вещей, которые вы можете сделать, чтобы повысить производительность вашего приложения:

1) AOT и Tree Shaking (angular-cli делает это из коробки). В Angular 9 AOT по умолчанию используется в среде prod и dev.

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 Я уверен , что есть простой способ оптимизировать его, но он близок к 250Кб!
Жак Корна
2
@JacquesCornat выглядит хорошо! Но ваше приложение состоит только из одного компонента. Вопрос в том, как управлять размерами пакетов или более крупными приложениями. Часто AOT недостаточно уменьшает размер пакетов, и люди вынуждены искать другой способ оптимизации. Я настоятельно рекомендую всем попробовать webpack-bundle-analyzer. Очень полезный / простой способ увидеть, что вызывает вздутие живота
Джек Клэнси
К сожалению, такие утилиты, как sw-precacheотказываются работать с пакетами поставщиков, размер которых превышает 2 МБ.
1
@JackClancy «Вопрос в том, как управлять размерами пакетов или более крупными приложениями». Нет его вопрос: "Как улучшить размер этого пакета?" и он говорит о своем минимальном приложении с 3 компонентами. В любом случае, говоря о больших пакетах, с использованием конфигурации AngularClass / angular-starter, как и в моем репо, размер моего пакета для больших приложений увеличился с 8 МБ (4 МБ без файлов карты) до 580 КБ.
Жак Корна 05
1
Спасибо, ты спас меня. --prod уменьшил размер приложения с 6 МБ до 1,2 МБ. Все еще не идеально, но приемлемо, поскольку он предназначен только для настольного использования.
Вячеслав Цивина
21

Используйте последнюю версию angular cli и используйте команду ng build --prod --build-optimizer. Это определенно уменьшит размер сборки для prod env.

Вот что делает оптимизатор сборки под капотом:

Оптимизатор сборки выполняет две основные задачи. Во-первых, мы можем пометить части вашего приложения как чистые, это улучшает встряхивание дерева, обеспечиваемое существующими инструментами, удаляя дополнительные части вашего приложения, которые не нужны.

Во-вторых, оптимизатор сборки удаляет декораторы Angular из кода времени выполнения вашего приложения. Декораторы используются компилятором, не требуются во время выполнения и могут быть удалены. Каждое из этих заданий уменьшает размер ваших пакетов JavaScript и увеличивает скорость загрузки вашего приложения для ваших пользователей.

Примечание : одно обновление для Angular 5 и выше, ng build --prodавтоматически позаботится о вышеуказанном процессе :)

Шубхенду Вайд
источник
1
Что касается angular 6 прямо сейчас, у поставщика все еще есть 4 МБ для установки только angular / material и
firebase
Это проблема с angular / material, даже я столкнулся с этой ошибкой. Вероятно, основной причиной является некорректное сотрясение дерева. С новым движком рендеринга IVY, вероятно, это будет решено.
Шубхенду Вайд,
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,08 МБ.
Stefdelec
Это немного! Есть ли у вас еще что-нибудь, импортирующее lodash по-старому? Вы не получите никакой помощи, если все не будет импортировано по-новому.
Эрик Саймонтон
Думаю, я все заменил. В противном случае размер не изменился бы. Ниже я дал еще один совет (вещь с gzip), который нам действительно помог.
Stefdelec
Интересный. Насколько сильно lodash вносит свой вклад в ваш пакет? (Например, используя source-map-explorer.)
Эрик Саймонтон
11

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

Для упаковки для производства я лично использую Webpackangular-cli тоже полагается на него ), потому что вы действительно можете configure everythingоптимизировать или отладить.
Если вы хотите использовать Webpack, я согласен, что это немного сложно на первый взгляд, но посмотрите учебные пособия в сети, вы не будете разочарованы.
В противном случае используйтеangular-cli , которые делают работу действительно хорошо.

Использование предварительной компиляции обязательно для оптимизации приложений и уменьшения размера приложения Angular 2 до 250 КБ .

Вот репо, которое я создал ( github.com/JCornat/min-angular ) для проверки минимального размера пакета Angular, и я получил 384 КБ . Я уверен, что есть простой способ его оптимизировать.

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

Жак Корнат
источник
Какая конкретная конфигурация angular-starter помогает уменьшить размер пакета? Это файл webpack.config?
MartinJH
2
Да, именно конфигурация веб-пакета уменьшает размер пакета.
Jacques Cornat
Спасибо за разъяснения :)
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"
      ]
    }

Это сделает ваш размер сборки намного меньше. В моем проекте я уменьшил размер с 11 МБ до 1 МБ. Надеюсь, поможет

Ренил Бабу
источник
5

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

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

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

После удаления Angular2-moment и использования DatePipe вместо

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

Обратите внимание, что комплект поставщика уменьшился на половину мегабайта!

Дело в том, что стоит проверить, что могут делать стандартные пакеты angular, даже если вы уже знакомы с внешней библиотекой.

kwalski
источник
1

Если вы бежали ng build --prod- не надоvendor файлов.

Если просто бегу ng build- получаю такие файлы:

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

Общий размер папки ~ 14 МБ. Waat! : D

Но если бегу ng build --prod- получаю такие файлы:

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

Общий размер папки 584К.

Один и тот же код. Я включил Ivy в обоих случаях. Angular - это 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% ng build --prod --aot --build-optimizer --vendor-chunk = true

АДЖАЙ АВХАД
источник
0

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

Также по умолчанию --aot и --build-optimizer включены в режиме --prod, вам не нужно указывать их отдельно.

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

sah1
источник
0

Убедитесь, что у вас есть конфигурация с именем "production" для ng build --prod, поскольку это сокращение от ng build --configuration = production. Моя проблема не решена, потому что проблема находилась прямо перед экраном. Я думаю, что это может быть довольно распространенным явлением ... Я интернационализировал приложение с i18n, переименовав все конфигурации, например, в production-en. Затем я построил с помощью ng build --prod, предполагая, что используется оптимизация по умолчанию и должна быть близка к оптимальной, но на самом деле была выполнена только сборка ng, в результате чего получился пакет 7 МБ вместо 250 КБ.

антидот
источник
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 МБ после сжатия.

Bat0u89
источник