前言
随着业务的代码一点点增加,加上Angular的项目本身就比 vue、react 的重一些,随之而来的启动速度,更改文件后编译速度,以及打包速度也会变慢,于是乎想着优化下我们的项目。
本文章主要说的是 :
- 打包Angular项目的一些配置,性能优化方面的方案
- 打包后,用户进入页面的速度提升
禁止Rollup 摇树优化
所谓Rollup是指Webpack2会把那些应用中未使用的引用代码除掉,但不会删除这些代码,所以就需要配合 UglifyJs 能够智能的移除这些未使用的代码。从而减少包体大小。
而Agnular应用是基于Typescript,因此Angular Cli提供了一个叫 Angular Build Optimizer 插件,将 Typescript 编译结果转化成更友好的UglifyJs版本。这样UglifyJs就能够更有效的移除那些未使用的代码。
Angular Cli只需要加上 --build-optimizer 参数就可以,这将禁用供应商数据块,并导致代码更小。在一些情况下压缩的还是很厉害的。
在package.json 打包命令的地方
- –build-optimizer=true
"build-uat": "ng build --prod --configuration=uat --build-optimizer=true",
build-optimizer的 true 与 false 区别
这里说的是package.json 的打包命令
true
- –build-optimizer=true
默认情况下会启用Tree-Shaking。但是虽然减小了构建大小(只会减小几kb),打包的速度会增加
- 打包后大小 36.6M
false
- –build-optimizer=false
不使用摇树优化,牺牲打包空间换取时间
禁用构建优化器。构建优化器是 Angular CLI 的一个特性,它可以对代码进行进一步的优化,包括移除未使用的代码、缩小构建输出等。
- 打包后大小 38.6M
对比
综上对比之下,开启与不开启差了 2M 左右,开启 true 后打包后的体积会变小,反之false 打包时间快 但是包变大。
时间与空间看个人选择了
Angular–AOT(预编译)
Angular编译主要有 AOT和JIT编译模式
- JIT 编译是在应用运行时进行的动态编译,而 AoT 编译是在构建过程中进行的预先编译。AoT 编译生成的代码体积较小、启动时间更快,并提供更好的性能。因此,对于生产环境的 Angular 应用,推荐使用 AoT 编译来获得更好的用户体验和性能。
- AoT 编译可以提供更小的代码体积和更好的性能,但在开发过程中可能会增加构建时间。因此,通常建议在生产环境中使用 AoT 编译,而在开发环境中使用 JIT(Just-in-Time)编译。
开启AoT
带有 --prod 标志的 ng build 命令 (ng build --prod) 会默认使用 AOT 编译
"build-uat": "ng build --prod",
路由开启预加载
在 Angular 中,可以通过在app-routing.module.ts路由配置中设置 preloadingStrategy 来定义预加载策略。preloadingStrategy 可以接受以下几个值:
PreloadAllModules
该策略会在应用程序启动后立即开始预加载所有惰性加载的模块。这意味着在用户导航到相关路由时,这些模块已经提前加载完成,因此用户会获得更快的加载体验。
- 优点:所有惰性加载模块都会在后台预加载,因此当用户导航到相关路由时,它们可以更快地加载和呈现。这对于提供更快的用户体验和降低延迟非常有帮助。
- 缺点:由于所有惰性加载模块都会在应用初始化期间加载,因此首屏加载时间可能会延长。如果应用中有大量的惰性加载模块或模块较大,可能会导致首屏加载时间增加,影响首次渲染速度。
NoPreloading
该策略表示不进行任何预加载操作。只有当用户导航到某个惰性加载的路由时,相关模块才会被加载。
- 优点:NoPreloading 策略可以减少首屏加载时间,因为只有核心模块和首屏需要的模块会在初始化期间加载。这可以帮助加快首次渲染速度。
- 缺点:当用户导航到其他路由时,惰性加载的模块需要额外的网络请求和编译时间,可能会导致稍微延迟加载的模块的首次渲染速度。
自定义预加载策略
创建自定义的预加载策略,实现更精细的控制。自定义预加载策略需要实现PreloadingStrategy 接口,并在该接口的 preload() 方法中定义预加载的行为。可以根据自己的需求,选择在何时、何地以及如何预加载模块。
自定义预加载策略总的来说,我认为可以,但完全没有必要。
import { Routes, RouterModule, RouteReuseStrategy, PreloadAllModules, NoPreloading } from '@angular/router';
import { NgModule } from '@angular/core';
// ...引入一堆
const routes: Routes = [
// 路由配置
];
@NgModule({
imports: [
//...引入各种业务路由
RouterModule.forRoot(routes, {
useHash: true,
onSameUrlNavigation: 'ignore',//ignore||reload
//PreloadAllModules:该策略会在应用程序启动后立即开始预加载所有惰性加载的模块。这意味着在用户导航到相关路由时,这些模块已经提前加载完成,因此用户会获得更快的加载体验。
//NoPreloading 策略则不进行任何预加载,只有当用户导航到某个模块时才会进行加载。这意味着初始加载时间会较快,但在导航到其他模块时可能会有稍微的延迟。
preloadingStrategy: PreloadAllModules,
//ignore:表示忽略相同 URL 的导航。无论用户点击多少次同一个路由,都不会触发导航重新加载。
// reload:表示在相同 URL 的导航时重新加载路由。每次用户点击同一个路由时,都会重新加载该路由。
// default:表示使用默认的导航行为。默认情况下,Angular 会保持相同 URL 的导航不变,不重新加载路由。
}),
],
exports: [RouterModule]
})
export class AppRoutingModule { }
选择
如果你更关注首次渲染速度和尽快展示核心内容给用户,可以考虑使用 NoPreloading 策略。如果你更关注整体应用的加载性能和用户导航体验,可以选择 PreloadAllModules 策略。你也可以根据应用的具体情况,使用自定义的预加载策略来满足特定需求。
我选的是PreloadAllModules,欲速则不达,一时的快并不是真正的快,要可持续性快才是真的快
注意 :在 app-routing.module.ts设置过了策略,仅需设置一次,无需在其他业务路由再去设置
路由懒加载
这个过去在我们项目中,已经是懒加载的状态,所以无需做修改
写在最后
优化后的结果,整体上来说 虽然第一次会进入页面会加载比较多的 js,同上文所说,会在加载玩本页面的基础上,预加载其他理由的页面
进入下一个页面的速度就会快很多,下面是首次进入加载的 js