Angular生产版本构建的配置与优化
Angular生产版本构建基础配置
在Angular项目中,构建生产版本是将应用从开发状态转换为可部署到生产环境的关键步骤。首先,我们来看一下基础的构建配置。Angular CLI(命令行界面)是构建Angular应用的主要工具,它提供了一系列命令来简化构建过程。
在项目根目录下,angular.json
文件包含了项目的各种配置信息,其中与构建相关的配置位于architect.build
节点下。
基本构建命令
使用Angular CLI构建生产版本的基本命令是:
ng build --prod
--prod
标志告诉Angular CLI启用生产模式构建。这会触发一系列优化,比如启用AOT( Ahead - of - Time)编译、移除开发相关代码、压缩输出文件等。
angular.json中的基本配置
- 输出路径:
outputPath
指定了构建输出的目录。默认情况下,它被设置为dist/{project - name}
。例如:
{
"architect": {
"build": {
"outputPath": "dist/my - angular - app",
// 其他配置
}
}
}
- 资产处理:
assets
数组定义了哪些文件或目录需要被复制到输出目录。通常,我们会将src/assets
目录下的静态资源文件(如图片、字体等)包含进来:
{
"architect": {
"build": {
"assets": [
"src/favicon.ico",
"src/assets"
],
// 其他配置
}
}
}
- 样式和脚本:
styles
数组指定了项目中使用的样式文件,而scripts
数组用于包含项目中需要的第三方脚本。例如:
{
"architect": {
"build": {
"styles": [
"src/styles.css"
],
"scripts": []
}
}
}
如果项目使用了SCSS或其他CSS预处理器,还需要配置相关的加载器。例如,对于SCSS,需要在architect.build
中添加以下配置:
{
"architect": {
"build": {
"styles": [
"src/styles.scss"
],
"stylePreprocessorOptions": {
"includePaths": [
"src"
]
},
// 其他配置
}
}
}
优化构建性能
优化构建性能可以显著减少构建时间,特别是对于大型项目。以下是一些优化构建性能的方法。
启用多进程构建
Angular CLI从8.0版本开始支持多进程构建。通过启用多进程构建,可以利用多核CPU的优势,加快构建速度。要启用多进程构建,需要在angular.json
的architect.build
中添加builder
配置:
{
"architect": {
"build": {
"builder": "@angular - cli:browser - webpack",
"options": {
// 原有的options配置
},
"configurations": {
"production": {
// 原有的production配置
}
}
}
}
}
然后,在项目根目录下安装@angular - cli:browser - webpack
:
npm install @angular - cli:browser - webpack --save - dev
最后,在构建命令中添加--optimization=true
和--progress=true
标志:
ng build --prod --optimization=true --progress=true
代码拆分与懒加载
- 路由懒加载:Angular的路由懒加载是一种强大的优化技术。它允许我们在需要时才加载模块,而不是在应用启动时加载所有模块。在路由配置中,使用
loadChildren
属性来实现懒加载。例如:
const routes: Routes = [
{
path: 'feature - module',
loadChildren: () => import('./feature - module/feature - module.module').then(m => m.FeatureModule)
}
];
这样,当用户访问/feature - module
路径时,FeatureModule
才会被加载。
- 非路由模块懒加载:对于非路由模块,也可以使用动态导入来实现懒加载。例如,假设我们有一个
SharedModule
,可以这样实现懒加载:
import { Component } from '@angular/core';
@Component({
selector: 'app - lazy - load - example',
templateUrl: './lazy - load - example.component.html'
})
export class LazyLoadExampleComponent {
async loadSharedModule() {
const { SharedModule } = await import('./shared - module/shared - module.module');
// 这里可以使用SharedModule中的内容,例如注册服务等
}
}
优化AOT编译
-
AOT编译原理:AOT编译在构建时将Angular模板编译成JavaScript代码,而不是在运行时编译。这大大提高了应用的启动性能,因为在运行时无需再进行模板编译。
-
优化AOT编译选项:在
angular.json
的architect.build
中,可以配置aot
相关选项。例如,启用fullTemplateTypeCheck
可以在编译时进行更严格的模板类型检查,有助于发现模板中的错误:
{
"architect": {
"build": {
"aot": true,
"fullTemplateTypeCheck": true,
// 其他配置
}
}
}
优化输出文件大小
减小输出文件大小对于提高应用的加载速度至关重要。以下是一些优化输出文件大小的方法。
移除未使用的代码(Tree - shaking)
-
原理:Tree - shaking是一种通过静态分析代码,移除未使用的导出(函数、变量等)的技术。在Angular项目中,它与ES6模块系统紧密结合。
-
实现:Angular CLI在生产模式构建时默认启用Tree - shaking。为了确保Tree - shaking能够正常工作,我们需要遵循一些最佳实践。例如,在模块导出时,应避免使用通配符导出(
export * from './module';
),而是显式导出需要的内容:
// 不好的导出方式
export * from './shared - utils';
// 好的导出方式
export { someFunction, someVariable } from './shared - utils';
压缩与合并文件
- 压缩CSS和JavaScript:Angular CLI在生产模式构建时会自动压缩CSS和JavaScript文件。压缩可以显著减小文件大小,提高加载速度。在
angular.json
的architect.build
中,可以配置压缩相关选项。例如,对于JavaScript压缩,可以设置terser
相关选项:
{
"architect": {
"build": {
"optimization": true,
"terser": {
"compress": {
"drop_console": true
}
},
// 其他配置
}
}
}
drop_console
选项可以移除代码中的console.log
语句,进一步减小文件大小。
- 合并文件:减少文件请求数量也可以提高应用的加载速度。Angular CLI默认会将一些文件合并。例如,样式文件会被合并成一个或几个CSS文件,JavaScript文件也会根据配置合并。在
angular.json
中,可以通过styles
和scripts
数组的配置来控制文件的合并。
图片优化
-
压缩图片:在将图片包含到项目中之前,对图片进行压缩是减小文件大小的有效方法。有许多工具可以用于图片压缩,如
ImageOptim
(适用于Mac)、Compressor.io
(在线工具)等。 -
使用合适的图片格式:根据图片的内容,选择合适的图片格式。例如,对于照片类图片,JPEG格式通常是一个不错的选择;对于简单的图标或有透明度要求的图片,PNG格式可能更好;而对于支持动画的图片,GIF或WebP(如果浏览器支持)是可选的。在Angular项目中,可以在
assets
配置中指定不同格式图片的使用策略。例如:
{
"architect": {
"build": {
"assets": [
{
"glob": "**/*.{jpg,png,gif,webp}",
"input": "src/assets/images",
"output": "/images"
}
],
// 其他配置
}
}
}
构建环境配置
在实际开发中,我们通常需要针对不同的环境(如开发、测试、生产)进行不同的配置。Angular CLI提供了一种方便的方式来管理环境配置。
环境文件
在src/environments
目录下,有两个主要的环境文件:environment.ts
和environment.prod.ts
。environment.ts
用于开发环境的配置,而environment.prod.ts
用于生产环境的配置。例如,我们可能在开发环境中使用本地的API地址,而在生产环境中使用正式的API地址:
// environment.ts
export const environment = {
production: false,
apiUrl: 'http://localhost:3000/api'
};
// environment.prod.ts
export const environment = {
production: true,
apiUrl: 'https://api.example.com/api'
};
使用环境配置
在应用代码中,可以通过导入environment
对象来使用相应环境的配置。例如:
import { Injectable } from '@angular/core';
import { environment } from '../environments/environment';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private apiUrl = environment.apiUrl;
constructor() {}
getApiUrl() {
return this.apiUrl;
}
}
自定义环境配置
除了默认的开发和生产环境,我们还可以自定义其他环境配置。例如,我们可以创建一个environment.staging.ts
用于预发布环境。首先,复制environment.ts
文件并命名为environment.staging.ts
,然后修改其中的配置:
// environment.staging.ts
export const environment = {
production: false,
apiUrl: 'https://staging - api.example.com/api'
};
然后,在angular.json
的architect.build
的configurations
中添加新的环境配置:
{
"architect": {
"build": {
"configurations": {
"production": {
// 生产环境配置
},
"staging": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.staging.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
}
}
}
这样,我们就可以使用ng build --configuration=staging
命令来构建预发布环境的版本。
缓存策略配置
合理的缓存策略可以提高应用的加载速度,特别是对于经常访问的用户。在Angular生产版本构建中,我们可以配置缓存相关的策略。
浏览器缓存
- 设置缓存头:在服务器端,可以通过设置合适的缓存头来控制浏览器对静态资源的缓存。例如,对于JavaScript和CSS文件,可以设置较长的缓存时间,因为这些文件相对稳定,不会经常变化。而对于HTML文件,缓存时间可以相对较短,因为它可能包含一些动态内容。
在Node.js服务器中,可以使用express
框架来设置缓存头。例如:
const express = require('express');
const app = express();
app.get('/styles.css', (req, res) => {
res.set('Cache - Control','public, max - age=31536000'); // 缓存一年
// 返回styles.css文件内容
});
app.get('/*.html', (req, res) => {
res.set('Cache - Control','public, max - age=3600'); // 缓存一小时
// 返回HTML文件内容
});
- 版本控制与缓存失效:为了确保在文件内容更新时,浏览器能够获取到最新的版本,我们可以使用文件哈希。Angular CLI在生产模式构建时会自动为输出文件添加哈希值。例如,
main.js
文件可能会被命名为main.1234567890abcdef.js
。当文件内容发生变化时,哈希值也会改变,从而使得浏览器不会使用旧的缓存。
服务工作者(Service Worker)
-
原理与作用:服务工作者是一种在后台运行的脚本,它可以拦截网络请求,缓存资源,并在离线时提供内容。在Angular项目中,我们可以使用Angular Service Worker来实现离线缓存和更快的加载速度。
-
配置与使用:首先,确保项目中安装了
@angular/service - worker
包:
npm install @angular/service - worker --save
然后,在app.module.ts
中导入并注册服务工作者模块:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform - browser';
import { AppComponent } from './app.component';
import { ServiceWorkerModule } from '@angular/service - worker';
import { environment } from '../environments/environment';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
ServiceWorkerModule.register('ngsw - worker.js', {
enabled: environment.production
})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
接下来,运行ng add @angular/pwa
命令,该命令会自动配置一些与PWA(渐进式Web应用)相关的内容,包括服务工作者的配置。
在ngsw - config.json
文件中,可以进一步配置服务工作者的缓存策略。例如,配置缓存的资源类型和过期时间:
{
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/*.css",
"/*.js"
]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"urls": [
"/assets/**"
]
}
}
]
}
通过以上配置,服务工作者会按照指定的策略缓存应用的资源,从而提高应用的性能和离线可用性。
性能监控与分析
在完成构建配置与优化后,对生产版本进行性能监控与分析是非常重要的,它可以帮助我们发现潜在的性能问题,并进一步优化应用。
使用Chrome DevTools
- 性能面板:Chrome DevTools的性能面板提供了丰富的工具来分析应用的性能。我们可以录制一段应用运行的性能数据,包括页面加载、脚本执行、渲染等各个方面。在录制过程中,我们可以执行一些关键操作,如导航到不同页面、触发动画等。
例如,在录制性能数据后,我们可以查看各个函数的执行时间,找出性能瓶颈。如果发现某个函数执行时间过长,可以进一步优化该函数的算法或逻辑。
- Lighthouse:Lighthouse是Chrome DevTools中的一个工具,它可以对网页进行全面的性能评估,并给出优化建议。它从性能、可访问性、最佳实践、SEO等多个维度对应用进行打分。
在Chrome DevTools中打开Lighthouse面板,选择要分析的页面,然后点击“Generate report”按钮,Lighthouse会生成一份详细的报告。例如,如果报告指出某个图片文件过大,我们可以按照前面提到的图片优化方法进行处理;如果报告提示脚本阻塞了渲染,我们可以优化脚本的加载和执行顺序。
使用WebPageTest
WebPageTest是一个在线的性能测试工具,它可以模拟不同的网络环境和地理位置对网页进行测试。通过在WebPageTest上输入Angular应用的URL,我们可以获取到应用在不同网络条件下的加载时间、资源大小等详细信息。
例如,我们可以选择模拟3G网络环境,查看应用在较慢网络下的表现。如果发现加载时间过长,我们可以针对性地优化资源大小、减少请求数量等。WebPageTest还提供了瀑布图,展示了每个资源的加载顺序和时间,有助于我们分析资源加载过程中的问题。
自定义性能监控
除了使用现有的工具,我们还可以在应用中添加自定义的性能监控代码。例如,使用performance
API来记录关键事件的时间。假设我们想记录某个组件的初始化时间,可以这样做:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app - custom - performance - monitor',
templateUrl: './custom - performance - monitor.component.html'
})
export class CustomPerformanceMonitorComponent implements OnInit {
constructor() {}
ngOnInit() {
const startTime = performance.now();
// 组件初始化逻辑
const endTime = performance.now();
console.log(`Component initialization time: ${endTime - startTime} ms`);
}
}
通过这种方式,我们可以深入了解应用内部各个部分的性能情况,从而进行更精准的优化。
通过以上全面的Angular生产版本构建的配置与优化方法,我们可以显著提高应用的性能,为用户提供更好的体验。无论是构建性能、输出文件大小,还是缓存策略和性能监控,每个环节都相互关联,共同影响着应用在生产环境中的表现。在实际项目中,需要根据项目的特点和需求,灵活运用这些方法,不断优化应用的性能。