我有一个
Angular 16
应用程序,最近已迁移到独立组件,并且我能够从整个代码库中删除所有模块。该应用程序出于 SEO 目的设置了 SSR,我通常会收到来自灯塔的警告,指示我应该尝试减少未使用的 javascript。
然后我尝试优化 main.js 文件,这是我拥有的最大的 JS 文件,并且我查看了 Angular 站点中的英雄之旅示例。我运行了
ng build --configuration production
,得到了 main.***.js
的 320Kb
文件(如果将其压缩到客户端,您将获得大约 100Kb)。
看看我的应用程序,我有
348Kb
,与《英雄之旅》示例相比,这还不错,并且仅为中型应用程序添加了 28Kb。有什么办法可以减小该文件的大小吗?
也许我们可以获得更小的块,这可能会更有效,但现在我已经运行了
webpack-bundle-analyzer
,我得到了以下结果:
对我来说这似乎相当不错。我认为我的
app.component
可能会引入额外的依赖项,但事实并非如此。
查看我的
main.ts
文件:
import { AppComponent } from './app/app.component';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideHttpClient } from '@angular/common/http';
import { bootstrapApplication, provideClientHydration } from '@angular/platform-browser';
import { provideRouter, withEnabledBlockingInitialNavigation, withInMemoryScrolling, withRouterConfig } from '@angular/router';
import routes from './app/app.routes';
bootstrapApplication(AppComponent, {
providers: [
provideHttpClient(),
provideAnimations(),
provideRouter(routes,
withInMemoryScrolling({
scrollPositionRestoration: 'top',
anchorScrolling: 'enabled',
}),
withEnabledBlockingInitialNavigation(),
withRouterConfig({
paramsInheritanceStrategy: 'always',
onSameUrlNavigation: 'reload'
})
),
provideClientHydration()
]
})
.catch(err => console.error(err));
我的生产版本的
angular.json
看起来像这样(非常标准):
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"outputPath": "dist/browser",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets",
"src/robots.txt",
"src/ads.txt",
{
"glob": "**/*",
"input": "node_modules/leaflet/dist/images/",
"output": "./assets"
}
],
"styles": [
"src/styles.scss"
],
"scripts": [],
"customWebpackConfig": {
"path": "webpack.config.js"
}
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "10kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all",
"buildOptimizer": true,
"aot": true,
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
}
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
请注意,
webpack.config.json
是为了最小化CSS,仅此而已;并且 inlineCriticalCss 标志设置为 false,因为禁用它实际上有更好的性能服务器端(https://github.com/angular/universal/issues/2106)
我的
app.component.ts
也很小,只是直接导入RouterOutlet的引用而已。
我一直在查看许多帖子和文章,我主要发现了我已经在做的延迟加载方法,并且我还延迟了应用程序的许多元素的引用和加载,以便可以以最快的方式完成引导程序。
您需要延迟加载模块。
如果这是一个新项目,您宁愿立即切换到独立组件并使用独立 API 引导您的应用程序。
关于延迟加载组件,你可以这样做:
export const APP_ROUTES: Routes = [
// Not lazyloaded
{
pathMatch: "full",
path: "",
component: HomeComponent,
data: { animation: "home" },
},
// lazyloaded standalone component
{
pathMatch: "full",
path: "actualite",
loadComponent: () =>
import(
"../components/pages/articles-home-page/articles-home-page.component"
).then((m) => m.ArticlesHomePageComponent),
data: { animation: "articlesHomePage" },
},
]
如果您使用导出默认值导出组件,则可以使用更短的语法。
loadComponent: () =>
import(
"../components/pages/articles-home-page/articles-home-page.component",
对于使用相同前缀的路由,您也可以将它们重新分组到导出路由数组的单个文件中,然后将其与 loadChildren:
一起使用 {
path: "clients",
loadChildren: () =>
import("./customer.routing").then((m) => m.CUSTOMER_ROUTES),
},
避免使用 commonJS 模块,如“moment”、“slugify”...,因为它们会产生更大的包(不是 treesshakble)
就这样结束了。