Оптимизация бандлов — ключевой этап подготовки Angular-приложения к продакшену. Вот комплексный подход, который я использую в проектах:
Используйте инструменты для понимания текущего состояния:
npx source-map-explorer dist/app-name/main.*.js
или
npm install -g webpack-bundle-analyzer
webpack-bundle-analyzer dist/stats.json
Что ищем:
Самая значительная оптимизация — разделение кода:
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
}
];
Эффект:
Убедитесь, что в tsconfig.json
:
{
"compilerOptions": {
"module": "esnext",
"target": "es2015"
}
}
Важно: Используйте ES-модули в сторонних библиотеках.
import cloneDeep from 'lodash/cloneDeep';
// Вместо: import { cloneDeep } from 'lodash';
import { MatButtonModule } from '@angular/material/button';
// Вместо: import { MaterialModule } from '@angular/material';
В angular.json
:
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"aot": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
}
]
}
}
Добавьте сжатие при билде:
npm install compression-webpack-plugin --save-dev
И настройте в angular.json
:
"customWebpackConfig": {
"path": "./extra-webpack.config.js"
}
Angular CLI автоматически генерирует:
Проверьте в browserslist
:
> 0.5%
last 2 versions
not dead
not IE 9-11
Комбинируйте lazy loading с предзагрузкой:
import { PreloadAllModules } from '@angular/router';
RouterModule.forRoot(routes, {
preloadingStrategy: PreloadAllModules
})
Или кастомная стратегия:
@Injectable()
export class CustomPreloading implements PreloadingStrategy {
preload(route: Route, load: () => Observable<any>): Observable<any> {
return route.data?.preload ? load() : of(null);
}
}
Кеширование бандлов:
ng add @angular/pwa
Настройка в ngsw-config.json
:
{
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": ["/*.bundle.css", "/*.bundle.js"]
}
}
]
}
В tsconfig.app.json
:
{
"angularCompilerOptions": {
"enableIvy": true,
"compilationMode": "partial"
}
}
const worker = new Worker('./app.worker', { type: 'module' });
worker.postMessage(data);
ng add @nguniversal/express-engine
Оптимизация — итерационный процесс. Начинайте с самых эффективных методов (Lazy Loading, анализ бандлов), затем переходите к более тонким настройкам. Для enterprise-приложений комбинируйте все подходы.