Angular2 CLI огромный вендор комплект: как улучшить размер для прод?

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

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

Но, несмотря на то, что мое приложение действительно простое, я получаю ОГРОМНЫЙ (на мой взгляд) пакет и карты. Я не говорю о версиях GZIP, но размер до GZIP. Этот вопрос только общие рекомендации.

Результаты некоторых тестов:

нг построить

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

кусок {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 кБ {4} [начальный] [визуализированный]

chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 кБ {4} [начальный] [обработанный]

кусок {3} vendor.bundle.js, vendor.bundle.map (vendor) 3,96 МБ [начальный] [обработанный]

кусок {4} inline.bundle.js, inline.bundle.map (inline) 0 байт [entry] [rendered]

Подождите: 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 (styles) 154 кБ {4} [начальный]

chunk {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.bundle.map (scripts) 128 кБ {4} [начальный] [обработанный]

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

кусок {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (inline) 0 байт [entry] [rendered]

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

ng build --prod --aot

Хеш: 517e4425ff872bbe3e5b Время: блок 22856ms {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 (styles) 154 кБ {4} [начальный] [обработанный]

chunk {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (scripts) 128 кБ {4} [начальный] [обработанный]

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

кусок {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map (inline) 0 байт [entry] [rendered]

ng build --aot

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

кусок {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 кБ {4} [начальный] [визуализированный]

chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 кБ {4} [начальный] [обработанный]

кусок {3} vendor.bundle.js, vendor.bundle.map (поставщик) 2,75 МБ [начальный] [обработанный]

кусок {4} inline.bundle.js, inline.bundle.map (inline) 0 байт [entry] [rendered]

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

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

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

16 ответов

Решение

Обновление октябрь 2018

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

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

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

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

1) AOT & Tree Shaking (angular-cli делает это из коробки)

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. Я верю / надеюсь, что Google знает о недостатках с точки зрения производительности и планирует улучшить это в будущем.

Вот ссылка, которая более подробно рассказывает о некоторых из упомянутых выше концепций:

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

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

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

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

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

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

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

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

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

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

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

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

Все ответы здесь устарели. Я только что создал стандартное шаблонное приложение Angular под названием «Tour of Heroes» с помощью Angular 13 CLI. Первоначальная сборка продукта заняла 10 секунд, последующая завершилась за 3 секунды. Размер пакета до Gzip составляет 244 КБ . Для сборки я использовал команду «ng build», никаких изменений в шаблонном проекте.

По этой теме много дезинформации. Выкладываем факты.

Размер папки сборки в байтах по фреймворку, файлы .map удалены, без gzip.

  • Angular 13.0.0 - 264563 (новые angular-tour-of-heroes, scss, router)
  • React 17.0.2 - 167074 (npx create-response-app my-app, без маршрутизатора)

В следующем решении предполагается, что вы используете папку 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 МБ. Надеюсь, поможет

обновление: 23.05.2022 с угловым 14 (RC1)

g-zipа также ng build --prodэто два решения, которые очень полезны. Это вам очень поможет. Но что, если бы вы сделали что-нибудь, старались изо всех сил. и все равно не работает? с помощью модуля ленивой загрузки. все еще не работает?

Вот ответ для вас. В настоящее время я обновляю свой проект Angular 13 до Angular 14, используя nx, и я узнаю, что «побочный эффект ствола» вызывает ваш main.jsувеличение пучка. Решение простое.

  1. изменить свой tsconfig.jsonпостроить модуль из "module": "commonjs"к "module": "es2020"или esnext (вы должны использовать объяснение es2020 здесь https://angular.io/guide/migration-update-module-and-target-compiler-options)

  2. добавить в package.jsonи посмотреть результат:

Почему?

полное объяснение здесь https://webpack.js.org/guides/tree-shaking/#conclusion и здесь и здесь /questions/53683262/napilnik-v-bochke-i-tryaska-dereva/53683272#53683272 . Но я могу сократить это для вас:

у вас есть модуль "А маленький" и "Б большой". вы пишете их в библиотеке пользовательского интерфейса и экспортируете их оба в index.tsфайл. вы импортируете A в свой проект. окончательный пакет по-прежнему включает B, который вам не нужен.

Почему?

потому что commonjsне умный. с использованием es2020лучше, они понимают, что полезно, а что нет. Но они не уверены, должны ли они быть удалены или нет. вы добавляете sideEffects: falseсказать им: «очистить мертвый код безопасно». и они сделали это. Тогда у вас маленький пакет. это можно использовать в любой современной среде JS, включая React, VueJS

прочитайте вопрос в проекте angular о побочном эффекте ствола здесь: https://github.com/angular/angular-cli/issues/16799https://github.com/angular/angular-cli/issues/16799

p/s: мой производственный веб-сайт angular находится здесь: https://awread.vn со 100 пользователями в день.

Еще один способ уменьшить пакет, это служить GZIP вместо JS. Мы пошли от 2,6 МБ до 543ko.

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

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

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

chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js (polyfills) 191 кБ {4} [начальный] [обработанный] chunk {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 байт [entry] [rendered]

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

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

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

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

Работает 100% ng build --prod --aot --build-optimizer --vendor-chunk=true

Это уменьшило размер в моем случае:

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

Размер после выполнения этой команды уменьшился с 1,7 МБ до 1,2 МБ, но этого недостаточно для моей производственной цели.

Я работаю на платформе мессенджера Facebook, и приложения мессенджера должны быть меньше 1 МБ для работы на мессенджере. Я пытался найти решение для эффективной встряски дерева, но все же не повезло.

If you are using Angular 8+ and you want to reduce the size of the bundle you can use Ivy. Ivy comes as the default view engine in Angular 9 Just go to src/tsconfig.app.json and add the angularCompilerOptions parameter, for example:

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

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

Взято из angular docs v9 (https://angular.io/guide/workspace-config):

По умолчанию определена производственная конфигурация, и команда 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 МБ после сжатия.

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

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

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

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

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

Один и тот же код. Я включил Ivy в обоих случаях. Angular - это 8.2.13.

Итак - я думаю, вы не добавили --prod вашей команде сборки?

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

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

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

/questions/25604683/ispolzovanie-szhatiya-gzip-s-spring-bootmvcjavaconfig-s-restful/25604708#25604708

Другие вопросы по тегам