One essential tactic for enhancing the scalability and performance of web applications is caching. Caching can be done in a variety of methods inside the frameworks of Angular (a client-side framework) and.NET Core (a server-side framework), each appropriate for a particular set of circumstances. The following are some typical caching techniques for both:

Angular Caching
Caching HTTP Requests with an HTTP Interceptor

  • To cache HTTP responses, use an HTTP interceptor. By delivering cached responses when appropriate, this can assist lower the amount of HTTP queries made to the server.
  • For instance. Construct an HTTP interceptor that looks through the cache before sending a network request, and a caching service that saves responses.
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class CacheInterceptor implements HttpInterceptor {
  private cache = new Map<string, any>();
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.method !== 'GET') {
      return next.handle(req);
    }
    const cachedResponse = this.cache.get(req.url);
    if (cachedResponse) {
      return of(cachedResponse);
    }
    return next.handle(req).pipe(
      tap(event => {
        this.cache.set(req.url, event);
      })
    );
  }
}


Service Worker for Offline Caching
  • Use Angular's built-in service worker support to cache assets and API responses for offline access and faster load times.
  • Example. Enable the Angular service worker by running ng add @angular/pwa and configure caching in the ngsw-config.json file.
Local Storage or IndexedDB
Store data in the browser's local storage or IndexedDB for long-term caching. This can be useful for storing user preferences or large datasets that rarely change.
Example. Use Angular's localStorage or IndexedDB wrappers to store and retrieve data.
localStorage.setItem('key', JSON.stringify(data));
const cachedData = JSON.parse(localStorage.getItem('key'));

Caching in .NET Core
In-Memory Caching
Store cache data in the memory of the web server. This is useful for small amounts of data that change frequently.
Example. Use the IMemoryCache interface to cache data in memory.
public class MyService
{
    private readonly IMemoryCache _memoryCache;
    public MyService(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache;
    }
    public string GetData()
    {
        string cacheKey = "myCacheKey";
        if (!_memoryCache.TryGetValue(cacheKey, out string cachedData))
        {
            cachedData = "Data from database";
            _memoryCache.Set(cacheKey, cachedData, TimeSpan.FromMinutes(5));
        }
        return cachedData;
    }
}


Distributed Caching
  • Store cache data in a distributed cache like Redis or SQL Server. This is useful for data that needs to be shared across multiple servers.
  • Example. Use the IDistributedCache interface to cache data in Redis.
public class MyService
    {
        private readonly IDistributedCache _distributedCache;
        public MyService(IDistributedCache distributedCache)
        {
            _distributedCache = distributedCache;
        }
        public async Task<string> GetDataAsync()
        {
            string cacheKey = "myCacheKey";
            var cachedData = await _distributedCache.GetStringAsync(cacheKey);
            if (cachedData == null)
            {
                cachedData = "Data from database";
                await _distributedCache.SetStringAsync(cacheKey, cachedData, new DistributedCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
                });
            }
            return cachedData;
        }
    }

Response Caching Middleware
  • Cache HTTP responses at the server level to improve performance for subsequent requests.
  • Example. Configure response caching middleware in the Startup class.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCaching();
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseResponseCaching();
        app.Use(async (context, next) =>
        {
            context.Response.GetTypedHeaders().CacheControl =
                new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
                {
                    Public = true,
                    MaxAge = TimeSpan.FromSeconds(60)
                };
            await next();
        });
    }


Combining Angular and .NET Core Caching

To achieve optimal performance, you can combine caching strategies in Angular and .NET Core:

Client-Side Caching

Cache static assets and API responses in Angular using service workers or local storage.
Implement HTTP interceptors to cache responses and reduce server requests.

Server-Side Caching
Use in-memory or distributed caching in .NET Core to store frequently accessed data.
Implement response caching middleware to cache entire HTTP responses.

Conclusion
You can build a strong and effective caching strategy that greatly improves the efficiency and scalability of your Angular and.NET Core applications by utilizing both client-side and server-side caching.