typescript 48 lines · 7 steps

A custom preloading strategy in Angular

Control which lazy-loaded route modules preload — and when — using route data flags and a delay.

Explained by highlit
1import { Injectable } from '@angular/core';
2import { PreloadingStrategy, Route, Routes, RouterModule } from '@angular/router';
3import { NgModule } from '@angular/core';
4import { Observable, of, timer } from 'rxjs';
5import { mergeMap } from 'rxjs/operators';
6 
7@Injectable({ providedIn: 'root' })
8export class SelectivePreloadStrategy implements PreloadingStrategy {
9 preload(route: Route, load: () => Observable<unknown>): Observable<unknown> {
10 if (!route.data?.['preload']) {
11 return of(null);
12 }
13 
14 const delay = (route.data['preloadDelay'] as number) ?? 0;
15 return timer(delay).pipe(mergeMap(() => load()));
16 }
17}
18 
19const routes: Routes = [
20 {
21 path: 'dashboard',
22 loadChildren: () =>
23 import('./dashboard/dashboard.module').then((m) => m.DashboardModule),
24 data: { preload: true },
25 },
26 {
27 path: 'reports',
28 loadChildren: () =>
29 import('./reports/reports.module').then((m) => m.ReportsModule),
30 data: { preload: true, preloadDelay: 3000 },
31 },
32 {
33 path: 'admin',
34 loadChildren: () =>
35 import('./admin/admin.module').then((m) => m.AdminModule),
36 data: { preload: false },
37 },
38];
39 
40@NgModule({
41 imports: [
42 RouterModule.forRoot(routes, {
43 preloadingStrategy: SelectivePreloadStrategy,
44 }),
45 ],
46 exports: [RouterModule],
47})
48export class AppRoutingModule {}
01 / 01
STEP 01

Walkthrough

Space play ←→ step click any line
Three takeaways
  1. 1A PreloadingStrategy lets you decide per-route whether a lazy module downloads in the background after the app boots.
  2. 2Route data is a flexible channel for passing configuration into infrastructure like preloaders.
  3. 3Returning of(null) from preload cleanly opts a route out without loading its bundle.

Related explainers

typescript
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
import localeFrExtra from '@angular/common/locales/extra/fr';
import localeDe from '@angular/common/locales/de';

Locale-aware bootstrapping in Angular

i18n localization dependency-injection
Intermediate 8 steps
typescript
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import * as Joi from 'joi';
 

Validating env config at boot in NestJS

configuration schema-validation environment-variables
Intermediate 8 steps
typescript
import { Inject, Injectable, Logger } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
import { InjectRepository } from '@nestjs/typeorm';

A cache-aside country lookup in NestJS

cache-aside dependency-injection batch-lookup
Intermediate 8 steps
typescript
import { Injectable, effect, signal, computed } from '@angular/core';
 
interface Preferences {
  theme: 'light' | 'dark';

A signal-based preferences store in Angular

signals state-management persistence
Intermediate 7 steps
typescript
import { useEffect, useState } from "react";
 
interface Section {
  id: string;

Building a scroll-spy hook in React

custom-hooks intersectionobserver dom-observation
Intermediate 8 steps
typescript
import { Injectable, Scope, Inject, NotFoundException } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';
import { DataSource } from 'typeorm';

Per-tenant database connections in NestJS

multi-tenancy connection-pooling dependency-injection
Advanced 8 steps

Share this explainer

Here's the card — post it anywhere.

A custom preloading strategy in Angular — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code