Introduzione al Service Worker di Angular 5

di , in Angular,

La versione 5 di Angular introduce un nuovo meccanismo per migliorare le performance di startup dell'applicazione: un Service Worker. I Service Worker sono script che girano in background, non hanno accesso al DOM e, tra l'altro, agiscono come proxy HTTP che intercettano tutte le chiamate di rete effettuate dalla nostra applicazione. Le chiamate di rete comprendono non solo le richieste ce effettuiamo nel nostro codice, ma anche quelle effettuate dal browser per scaricare file HTML, JavaScript, CSS e così via.

Grazie alla capacità dei Service Worker di intercettare le chiamate HTTP, questi sono in grado di mettere in cache i file che compongono la nostra applicazione così che al successivo accesso questa sia caricata immediatamente senza bisogno di accedere alla rete. Inoltre, se la rete non è disponibile la nostra applicazione è comunque in grado di partire. Questo meccanismo permette di offrire una maggior usabilità all'utente che ha una miglior percezione della nostra applicazione.

Il Service Worker di Angular

Un'applicazione sviluppata con Angular è essenzialmente una Single Page Application (SPA) e come tale può ottenere grossi benefici dall'utilizzo di un Service Worker. Come detto, Angular 5 ne introduce uno specializzato che permette di mettere in cache l'applicazione. Non solo questo Service Worker ottimizza le prestazioni usando la cache, ma riduce anche il rischio più comune legato all'utilizzo della cache: l'utilizzo di dati obsoleti. Vediamo come funziona il Service Worker di Angular e come raggiunge questi obiettivi.

  • Innanzitutto, il Service Worker memorizza l'applicazione come un unico blocco di file. Questo significa che il Service Worker non memorizzerà mai all'interno di un blocco file appartenenti a versioni differenti della stessa applicazione. Questo garantisce l'integrità della nostra applicazione;
  • Quando l'utente apre l'applicazione, per ottimizzare lo startup l'applicazione viene servita dalla cache se disponibile. In caso contrario l'applicazione viene scaricata e il Service Worker la mette in cache;
  • Quando c'è una nuova versione della nostra applicazione sul server, il Service Worker se ne accorge e in background lancia l'aggiornamento della cache. Per ottimizzare l'utilizzo della rete, il Service Worker scarica solo i file effettivamente modificati.

Queste operazioni si basano sulla presenza sul server di un manifest. Questo file contiene le informazioni sui file dell'applicazione, come devono essere memorizzati in cache e il loro hash. Quando viene rilasciata una nuova versione dell'applicazione, il manifest cambia e il Service Worker comincia a scaricare la nuova versione.

Angular 5 e Angular CLI 1.6 contengono già il framework e gli strumenti di sviluppo per generare il file di manifest lato server e aggiungere il Service Worker alla nostra applicazione. Nella prossima sezione vedremo come utilizzare questi strumenti

Aggiungere il Service Worker a un'applicazione

Per aggiungere il Service Worker ad un'applicazione che stiamo creando da zero, tutto quello che dobbiamo fare è utilizzare il seguente commando di AngularCLI.

ng new my-app --service-worker

Lo switch --service-worker aggiunge all'applicazione il codice e i file necessari per il Service Worker così che non dobbiamo configurare nulla.

Nel caso in cui dobbiamo aggiungere il Service Worker a un'applicazione esistente, dobbiamo eseguire a mano i passaggi che lo switch --service-worker fa per noi quando creiamo l'applicazione da zero. Il primo step consiste nell'aggiungere il package @angular/service-worker all'applicazione tramite il seguente comando.

yarn add @angular/service-worker

Il secondo step consiste nell'aggiungere il Service Worker alla CLI per includerlo nel processo di build. Questo risultato può essere ottenuto o tramite riga di comando, o modificando il file .angular-cli.json. Nel caso in cui optiamo per la riga di comando dobbiamo utilizzare il seguente comando.

ng set apps.0.serviceWorker=true

Questo comando apre il file .angular-cli.json e aggiunge al primo elemento della proprietà apps la proprietà serviceWorker impostandola a true.

Se invece optiamo per la modifica manuale del file, dobbiamo eseguire manualmente la modifica appena menzionata.

Il terzo step consiste nel modificare il modulo principale dell'applicazione aggiungendo il ServiceWorkerModule e la classe environment. Il modulo va aggiunto alla lista di moduli da cui l'applicazione dipende.

import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ServiceWorkerModule.register('/ngsw-worker.js', {enabled: environment.production})
  ],
  providers: [
    CheckForUpdateService,
    LogUpdateService,
    PromptUpdateService,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { } 

Il metodo statico register specifica il nome del file che contiene il Service Worker e un oggetto la cui proprietà enabled specifica se abilitarlo o meno.

Il quarto e ultimo step consiste nella creazione del file ngsw-config.json. Questo file specifica come mettere in cache l'applicazione e serve per creare il file di manifest. Il contenuto di default di questo file è visibile nel prosimo esempio.

{
  "index": "/index.html",
  "assetGroups": [{
    "name": "app",
    "installMode": "prefetch",
    "resources": {
      "files": [
        "/favicon.ico",
        "/index.html"
      ],
      "versionedFiles": [
        "/*.bundle.css",
        "/*.bundle.js",
        "/*.chunk.js"
      ]
    }
  }, {
    "name": "assets",
    "installMode": "lazy",
    "updateMode": "prefetch",
    "resources": {
      "files": [
        "/assets/**"
      ]
    }
  }]
} 

La proprietà index specifica il file principale mentre la proprietà assetGroups contiene i file che l'applicazione deve memorizzare e in che modo vanno memorizzati. Se aggiungiamo altri asset in altre cartelle o se modifichiamo la struttura del progetto, dobbiamo modificare questo file per permettere un corretto caching delle risorse. Per maggiori informazioni su questo file di configurazione rimandiamo alla documentazione disponibile a questo indirizzo.

A questo punto la nostra applicazione è pronta per essere compilata e distribuita includendo il Service Worker. Tutto quello che dobbiamo fare è eseguire la build in modalità di produzione così che l'output della build finisca nella cartella dist.

Per vedere in azione il Service Worker dobbiamo lanciare un server HTTP diverso da quello lanciato dal comando ng serve in quanto questo non supporta i Service Worker. Per questo motivo usiamo http-server. Una volta installato dobbiamo spostarci nella cartella dist e in seguito usare il comando http-server -p 1234 per far partire il server.

Una volta avviato il server, apriamo il browser e navighiamo all'url http://localhost:1234 ottenendo come risultato la pagina iniziale della nostra applicazione. Successivamente disattiviamo http-server e proviamo a eseguire di nuovo l'applicazione. Poiché il Service Worker ha memorizzato in cache l'applicazione, vedremo la pagina iniziale nonostante il server sia giù.

Successivamente modifichiamo la view app.component.html cambiandone l'intestazione, eseguiamo la build di produzione e rilanciamo http-server. Se andiamo sul browser e rilanciamo l'applicazione otterremo ancora la vecchia versione. Questo avviene perché, come detto in precedenza, alla partenza il Service Worker fornisce sempre la versione in cache senza controllare se la versione sul server sia più recente. Subito dopo la partenza, il Service Worker controlla se esiste una versione aggiornata e la scarica. Per questo motivo, se rilanciamo di nuovo l'applicazione vedremo la nuova versione.

2 pagine in totale: 1 2
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

Introduzione al Service Worker di Angular 5 1010 1
| Condividi su: Twitter, Facebook, LinkedIn, Google+

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti