Caching assets in Angular application

Viewed 483

What is the current best practise for caching assets (images, pdfs, other downloadable documents) in an Angular application?

Let's assume I have a PDF document named agreement.pdf that is linked on a page of the web application and to be downloaded by the user. I deployed the app with nginx setting header Cache-Control: public, max-age=31536000 except for index.html that has no caching. Now I am changing the document, deploying and the user's browser that cached the document before must fetch the new version. Since angular doesn't hash assets, this will be a problem.

My current solution is to introduce cache-busting for assets. In my angular.json I specified:

...
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
      "options": {
        ...
        "assets": [
              {
                "glob": "**/*",
                "input": "src/assets/",
                "output": "/assets/0/"
              }
        ],
        ...

I also added a pipe

import { Pipe, PipeTransform } from '@angular/core';
import { environment } from 'src/environments/environment';

@Pipe({name: 'asset'})
export class AssetPipe implements PipeTransform {
  transform(value: string): string {
    return assetUrl(value);
  }
}

export function assetUrl(assetName: string) {
  return "assets/" + environment.assetVersion + "/" + assetName;
}

which can be used in templates where an asset is referenced, e.g. <img [src]="'agreement.pdf' | asset" />. The function assetUrl can be used in component code. The environment.ts reads like:

export const environment = {
  production: false,
  assetVersion: '0'
};

Now, whenever an asset has changed, I modify two places: environment.assetVersion and the asset path in angular.json. Advantage: Only two places to modify for a new assets versions. Disadvantage: All assets must be refetched even if individual ones have not changed.

What's your solution to the problem?

0 Answers
Related