Как уменьшить размер продукта?
У меня есть простое приложение, инициализированное angular-cli
.
Он отображает несколько страниц, относящихся к 3 маршрутам. У меня есть 3 компонента. На одной из этих страниц я использую HTTP-модули lodash
и Angular 2 для получения некоторых данных (используя RxJS Observable
s, map
и subscribe
). Я отображаю эти элементы с помощью простого *ngFor
.
Но, несмотря на то, что мое приложение действительно простое, я получаю огромный (на мой взгляд) пакет и карты. Я не говорю о версиях GZIP, но размер до GZIP. Этот вопрос является просто вопросом общих рекомендаций.
Результаты некоторых тестов:
нг сборка
Hash: 8efac7d6208adb8641c1 Time: 10129ms chunk {0} main.bundle.js,
main.bundle.map(main) 18.7 kB {3} [initial] [rendered]
chunk {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]
Подождите: 10-мегабайтный пакет поставщика для такого простого приложения?
ng build --prod
Hash: 09a5f095e33b2980e7cc Time: 23455ms chunk {0}
main.6273b0f04a07a1c2ad6c.bundle.js,
main.6273b0f04a07a1c2ad6c.bundle.map(main) 18.3 kB {3} [initial]
[rendered]
chunk {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css,
styles.bfdaa4d8a4eb2d0cb019.bundle.map,
styles.bfdaa4d8a4eb2d0cb019.bundle.map(styles) 154 kB {4} [initial]
[rendered]
chunk {2} scripts.c5b720a078e5464ec211.bundle.js,
scripts.c5b720a078e5464ec211.bundle.map(scripts) 128 kB {4} [initial]
[rendered]
chunk {3} vendor.07af2467307e17d85438.bundle.js,
vendor.07af2467307e17d85438.bundle.map(vendor) 3.96 MB [initial]
[rendered]
chunk {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map(inline) 0 байт [вход] [Вынесено]
Подождите еще раз: такой же размер пакета поставщика для продукта?
ng build --prod --aot
Hash: 517e4425ff872bbe3e5b Time: 22856ms chunk {0}
main.95eadabace554e3c2b43.bundle.js,
main.95eadabace554e3c2b43.bundle.map(main) 130 kB {3} [initial]
[rendered]
chunk {1} styles.e53a388ae1dd2b7f5434.bundle.css,
styles.e53a388ae1dd2b7f5434.bundle.map,
styles.e53a388ae1dd2b7f5434.bundle.map(styles) 154 kB {4} [initial]
[rendered]
chunk {2} scripts.e5c2c90547f3168a7564.bundle.js,
scripts.e5c2c90547f3168a7564.bundle.map(scripts) 128 kB {4} [initial]
[rendered]
chunk {3} vendor.41a6c1f57136df286f14.bundle.js,
vendor.41a6c1f57136df286f14.bundle.map(vendor) 2.75 MB [initial]
[rendered]
chunk {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map(inline) 0 байт [вход] [Вынесено]
ng build --aot
Hash: 040cc91df4df5ffc3c3f Time: 11011ms chunk {0} main.bundle.js,
main.bundle.map(main) 130 kB {3} [initial] [rendered]
chunk {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]
Итак, несколько вопросов по развертыванию моего приложения на Prod:
- Почему комплекты поставщиков такие огромные?
- Правильно ли используется встряхивание деревьев
angular-cli
?
- Как улучшить размер пакета?
- Требуются ли файлы .map?
- Функции тестирования включены в пакеты? Я не нуждаюсь в них в продуктах.
- Общий вопрос: какие рекомендуемые инструменты для упаковки продуктов? Может быть,
angular-cli
(с использованием Webpack в фоновом режиме) не самый лучший вариант? Можем ли мы сделать лучше?
Я искал много дискуссий о Кару, но я не нашел ни одного общего вопроса.
Ответы
Ответ 1
Обновление октябрь 2018
Поскольку этот ответ получил большую популярность, я подумал, что будет лучше обновить его с помощью более новых угловых оптимизаций:
- Как сказал другой участник,
ng build --prod --build-optimizer
- хороший вариант для людей, использующих менее Angular v5. Для более новых версий это делается по умолчанию с помощью ng build --prod
- Другой вариант - использовать чанкинг модулей/отложенную загрузку, чтобы лучше разделить ваше приложение на более мелкие порции.
- Механизм рендеринга плюща, пока еще не запущенный в производство, скоро предложит более качественные пакеты
- Удостоверьтесь, что ваши сторонние персонажи можно потрясти деревьями. Если вы еще не используете Rxjs v6, вам следует.
- Если ничего не помогает, используйте такой инструмент, как 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
Ответ 2
Используйте последнюю версию angular cli и используйте команду ng build --prod --build-optimizer Это определенно уменьшит размер сборки для prod env.
Вот что оптимизатор сборки делает под капотом:
Оптимизатор сборки выполняет две основные задачи. Во-первых, мы можем пометить части вашего приложения как чистые, это улучшает встряхивание дерева, обеспечиваемое существующими инструментами, удаляя дополнительные части вашего приложения, которые не нужны.
Второе, что делает оптимизатор сборки, - это удаление Angular-декораторов из кода времени выполнения ваших приложений. Декораторы используются компилятором и не нужны во время выполнения и могут быть удалены. Каждое из этих заданий уменьшает размер ваших пакетов JavaScript и увеличивает скорость загрузки вашего приложения для ваших пользователей.
Примечание: одно обновление для Angular 5, сборка ng --prod автоматически позаботится о вышеописанном процессе :)
Ответ 3
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
Ответ 4
Во-первых, пакеты поставщиков огромны просто потому, что Angular 2 опирается на множество библиотек. Минимальный размер приложения Angular 2 составляет около 500 КБ (в некоторых случаях 250 КБ, см. Нижнюю статью).
Встряхивание дерева должным образом используется angular-cli
.
Не включайте .map
файлы, так как используется только для отладки. Кроме того, если вы используете модуль горячей замены, снимите его, чтобы облегчить поставщика.
Для производства я лично использую Webpack (и angular-cli тоже полагается на него), потому что вы действительно можете configure everything
для оптимизации или отладки.
Если вы хотите использовать Webpack
, я согласен, что на первый взгляд это немного сложно, но посмотрите учебники в сети, вы не будете разочарованы.
Иначе, используйте angular-cli
, которые хорошо angular-cli
с работой.
Использование Опережающей компиляции является обязательным для оптимизации приложений и сокращения приложения Angular 2 до 250 КБ.
Вот репозиторий, который я создал (github.com/JCornat/min-angular), чтобы проверить минимальный размер углового пучка, и я получил 384 КБ. Я уверен, что есть простой способ оптимизировать его.
Говоря о больших приложениях, использующих конфигурацию AngularClass/angular-starter, как и в приведенном выше репо, размер моего пакета для больших приложений (компоненты 150+) увеличился с 8 МБ (4 МБ без файлов карт) до 580 КБ.
Ответ 5
В следующем решении предполагается, что вы используете папку 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
а внутри папки vendor создайте файл 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 МБ. Надеюсь, поможет
Ответ 6
Одна вещь, которую я хочу поделиться, - это то, как импортированные библиотеки увеличивают размер dist. Я импортировал пакет angular2 -moment, тогда как я мог делать все форматирование времени даты, которое мне нужно, используя стандартную DatePipe, экспортированную из @angular/common.
С angular2 -Moment "angular2-moment": "^1.6.0",
chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js(полипол) 191 kB {4} [начальный] [оказанный] фрагмент {1} main.e7496551a26816427b68.bundle.js(main) 2.2 MB {3} [начальный] [rendered] chunk {2} styles.056656ed596d26ba0192.bundle.css(стили) 69 байт {4} [начальный] [оказанный] фрагмент {3} vendor.62c2cfe0ca794a5006d1.bundle.js(поставщик) 3,84 МБ [начальный] [rendered] chunk {4} inline.0b9c3de53405d705e757.bundle.js(inline) 0 байт [запись] [отображается]
После удаления angular2 -moment и использования DatePipe вместо
chunk {0} polyfills.036982dc15bb5fc67cb8.bundle.js(полипол) 191 kB {4} [начальный] [оказанный] фрагмент {1} main.f2b62721788695a4655c.bundle.js(main) 2.2 MB {3} [начальный] [rendered] chunk {2} styles.056656ed596d26ba0192.bundle.css(стили) 69 байт {4} [начальный] [оказанный] фрагмент {3} vendor.e1de06303258c58c9d01.bundle.js(поставщик) 3,35 МБ [начальный] [rendered] chunk {4} inline.3ae24861b3637391ba70.bundle.js(inline) 0 байт [запись] [отображается]
Обратите внимание, что пакет поставщиков сократил половину мегабайта!
Точка - стоит проверить, что могут сделать стандартные пакеты angular, даже если вы уже знакомы с внешней библиотекой.
Ответ 7
Еще один способ уменьшить пакет, это служить GZIP вместо JS. Мы пошли от 2,6 МБ до 543ko.
https://httpd.apache.org/docs/2.4/mod/mod_deflate.html
Ответ 8
Это уменьшило размер в моем случае:
ng build --prod --build-optimizer --optimization
Размер после выполнения этой команды уменьшился с 1,7 МБ до 1,2 МБ, но этого недостаточно для моей производственной цели.
Я работаю на платформе мессенджера Facebook, и приложения мессенджера должны быть меньше 1 МБ, чтобы работать на платформе мессенджера. Я пытался найти решение для эффективной встряски дерева, но все же не повезло.
Ответ 9
У меня есть угловое 5 + пружинное загрузочное приложение (application.properties 1. 3+) с помощью сжатия (ссылка прилагается ниже) смогло уменьшить размер main.bundle.ts с 2,7 МБ до 530 КБ.
Также по умолчанию --aot и --build-optimizer включены в режиме --prod, вам не нужно указывать их отдельно.
fooobar.com/questions/99468/...
Ответ 10
Убедитесь, что у вас есть конфигурация с именем "production" для ng build --prod, так как это сокращенная версия для ng build --configuration = production Нет ответа, который решил мою проблему, потому что проблема находилась прямо перед экраном. Я думаю, что это может быть довольно распространенным... Я интернационализировал приложение с помощью i18n, переименовав все конфигурации, например, в production-en. Затем я построил с помощью ng build --prod, предполагая, что используется оптимизация по умолчанию и она должна быть близка к оптимальной, но на самом деле была выполнена только сборка ng, что привело к пакету 7 МБ вместо 250 КБ.
Ответ 11
Если вы используете Angular 8+ и хотите уменьшить размер пакета, вы можете использовать Ivy.
Просто перейдите в src/tsconfig.app.json и добавьте параметр angularCompilerOptions, например:
{
"extends": ...,
"compilerOptions":...,
"exclude": ...,
/* add this one */
"angularCompilerOptions": {
"enableIvy": true
}
}