Кэширование данных в Angular можно реализовать несколькими способами в зависимости от требований и архитектуры приложения. Рассмотрим основные подходы:
Самый простой способ - создать сервис, который будет хранить данные в памяти:
@Injectable({ providedIn: 'root' })
export class DataCacheService {
private cache = new Map<string, { data: any, expires: number }>();
get(key: string): any | null {
const item = this.cache.get(key);
if (!item) return null;
if (item.expires < Date.now()) {
this.cache.delete(key);
return null;
}
return item.data;
}
set(key: string, data: any, ttl: number = 60000): void {
this.cache.set(key, {
data,
expires: Date.now() + ttl
});
}
clear(key?: string): void {
if (key) {
this.cache.delete(key);
} else {
this.cache.clear();
}
}
}
Более продвинутый способ - реализовать кэширование HTTP-запросов:
@Injectable()
export class CacheInterceptor implements HttpInterceptor {
private cache = new Map<string, { expires: number, response: any }>();
constructor(private cacheService: DataCacheService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Кэшируем только GET-запросы
if (req.method !== 'GET') {
return next.handle(req);
}
const cachedResponse = this.cacheService.get(req.urlWithParams);
if (cachedResponse) {
return of(cachedResponse);
}
return next.handle(req).pipe(
tap(event => {
if (event instanceof HttpResponse) {
this.cacheService.set(req.urlWithParams, event);
}
})
);
}
}
Не забудьте зарегистрировать интерсептор в модуле:
@NgModule({
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }
]
})
export class AppModule {}
Для сложных сценариев можно использовать специализированные библиотеки:
ngx-cacheable
- предоставляет декораторы для кэширования@ngneat/cashew
- мощное решение для кэширования HTTP-запросовПример с @ngneat/cashew
:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { cache } from '@ngneat/cashew';
@Injectable()
export class DataService {
constructor(private http: HttpClient) {}
@Cache({
key: 'users',
ttl: 3600000 // 1 час
})
getUsers() {
return this.http.get('/api/users');
}
}
Для персистентного кэширования между сессиями:
@Injectable()
export class PersistentCacheService {
constructor() {}
set(key: string, data: any): void {
localStorage.setItem(key, JSON.stringify(data));
}
get(key: string): any {
const data = localStorage.getItem(key);
return data ? JSON.parse(data) : null;
}
}
Использование операторов RxJS для кэширования:
private cache$: Observable<Data[]>;
getData(): Observable<Data[]> {
if (!this.cache$) {
this.cache$ = this.http.get<Data[]>('/api/data').pipe(
shareReplay(1) // Кэшируем последнее значение
);
}
return this.cache$;
}
Инвалидация кэша - важно предусмотреть механизмы сброса кэша при:
Стратегии кэширования:
Размер кэша - важно ограничивать размер, чтобы не перегружать память.
в Angular есть множество способов реализовать кэширование - от простых in-memory решений до сложных стратегий с использованием интерсепторов и специализированных библиотек. Выбор зависит от конкретных требований вашего приложения.