Optimizing Angular application startup time is crucial to ensuring a smooth user experience. Here are some techniques to achieve faster load times:
1. **Differential Loading**: It’s a technique where the build process produces multiple bundles targeting different browsers with their specific capabilities. The browser automatically chooses the bundle that matches its compatibility, ensuring that older, less capable browsers get the required polyfills, while modern browsers can run the more optimized bundle. You can enable differential loading by setting the ‘target‘ option for TypeScript in the ‘tsconfig.json‘ file.
{
"compilerOptions": {
"target": "es2015"
}
}
2. **App Shell Technique**: The App Shell technique provides a fast-loading, cached "shell" of an application’s user interface that can be displayed immediately to the user, which is later replaced or updated with the actual content. You can implement the App Shell using Angular Universal and Angular Service Worker. Here are the steps:
a. Install Angular Universal:
ng add @nguniversal/express-engine
b. Implement App Shell component:
@Component({
selector: 'app-shell',
template: `Loading...`
})
export class AppShellComponent {}
c. Add App Shell to your ‘app.component.html‘:
<app-shell *ngIf="!isDataLoaded"></app-shell>
<div *ngIf="isDataLoaded">Your app content here</div>
d. Register Angular Service Worker in the ‘app.module.ts‘:
import { ServiceWorkerModule } from '@angular/service-worker';
@NgModule({
...
imports: [
...
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.production
})
]
})
export class AppModule { }
e. Configure ‘ngsw-config.json‘ to cache your assets and data:
{
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": ["/favicon.ico", "/index.html", "/*.css", "/*.js"]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": ["/assets/**"]
}
}
],
"dataGroups": [
{
"name": "api",
"urls": ["https://yourapi.example.com/data"],
"cacheConfig": {
"strategy": "performance",
"maxAge": "1d",
"maxSize": 100
}
}
]
}
f. Build and deploy your app with Angular Universal:
ng build --prod
ng run <your-app-name>:server
3. **Lazy Loading**: Lazy loading allows your application to load only the necessary code for a specific route, reducing the initial bundle size. You can implement lazy loading by using Angular’s ‘loadChildren‘ syntax in your route configuration.
const routes: Routes = [
{
path: 'route1',
loadChildren: () => import('./route1/route1.module').then(m => m.Route1Module)
},
{
path: 'route2',
loadChildren: () => import('./route2/route2.module').then(m => m.Route2Module)
},
];
4. **Ahead-of-Time (AOT) Compilation**: AOT compilation compiles the Angular components and templates at build time, converting them into JavaScript code, which removes the need for runtime compilation, reducing the overall bundle size and improving startup performance. AOT is enabled by default in Angular production builds:
ng build --prod
5. **Budgets**: You can set up performance budgets in ‘angular.json‘ configuration file to ensure that your application bundle sizes stay within a specified limit. Angular will generate a warning or an error if the budget threshold is crossed.
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
In addition to these techniques, you should minimize the use of third-party libraries, remove unused code, and utilize tree-shaking provided by Angular CLI to reduce your application size and improve startup performance.
Remember, performance optimization is an ongoing process, and you should continually monitor and optimize your application to ensure it remains fast and responsive.