Boostez votre application Web en migrant vers le SDK Firebase JS modulaire

1. Avant de commencer

Le SDK JS modulaire Firebase est une réécriture du SDK JS existant et sera publié en tant que prochaine version majeure. Il permet aux développeurs d'exclure le code inutilisé du SDK JS Firebase pour créer des bundles plus petits et obtenir de meilleures performances.

La différence la plus notable dans le SDK JS modulaire est que les fonctionnalités sont désormais organisées dans des fonctions flottantes que vous importerez, au lieu d'être dans un seul espace de noms firebase qui inclut tout. Cette nouvelle façon d'organiser le code permet l'élimination du code mort. Vous apprendrez à migrer n'importe quelle application utilisant actuellement le SDK JS Firebase v8 vers le nouveau SDK modulaire.

Pour que la mise à niveau se déroule sans problème, un ensemble de packages de compatibilité est fourni. Dans cet atelier de programmation, vous allez apprendre à utiliser les packages de compatibilité pour migrer l'application petit à petit.

Objectifs de l'atelier

Dans cet atelier de programmation, vous allez migrer progressivement une application Web de liste de suivi des actions existante qui utilise le SDK JS v8 vers le nouveau SDK JS modulaire en trois étapes :

  • Mettre à niveau l'application pour utiliser les packages de compatibilité
  • Migrer l'application des packages de compatibilité vers l'API modulaire, élément par élément
  • Utilisez Firestore Lite, une implémentation allégée du SDK Firestore, pour améliorer encore les performances de l'application.

2d351cb47b604ad7.png

Cet atelier de programmation porte sur la mise à niveau du SDK Firebase. Les autres concepts et blocs de code ne sont pas abordés, mais vous sont fournis afin que vous puissiez simplement les copier et les coller.

Prérequis

  • Un navigateur de votre choix, tel que Chrome
  • L'IDE/éditeur de texte de votre choix, tel que WebStorm, Atom, Sublime ou VS Code
  • Le gestionnaire de packages npm, qui est généralement fourni avec Node.js
  • L'exemple de code de l'atelier de programmation (voir l'étape suivante de l'atelier de programmation pour savoir comment obtenir le code)

2. Configuration

Obtenir le code

Tout ce dont vous avez besoin pour ce projet se trouve dans un dépôt Git. Pour commencer, vous devez récupérer le code et l'ouvrir dans l'environnement de développement de votre choix.

Clonez le dépôt GitHub de l'atelier de programmation à partir de la ligne de commande :

git clone https://github.com/FirebaseExtended/codelab-modular-sdk.git

Si vous n'avez pas installé git, vous pouvez également télécharger le dépôt sous forme de fichier ZIP et décompresser le fichier ZIP téléchargé.

Importer l'application

  1. Ouvrez ou importez le répertoire codelab-modular-sdk à l'aide de votre IDE.
  2. Exécutez npm install pour installer les dépendances nécessaires à la création et à l'exécution de l'application en local.
  3. Exécutez npm run build pour compiler l'application.
  4. Exécutez npm run serve pour démarrer le serveur Web.
  5. Ouvrez http://localhost:8080 dans un nouvel onglet de votre navigateur.

71a8a7d47392e8f4.png

3. Établir une référence

Point de départ

Vous allez utiliser une application de liste de suivi des actions conçue spécialement pour cet atelier de programmation. Nous avons simplifié le code pour illustrer les concepts abordés dans cet atelier de programmation, c'est pourquoi il offre peu de gestion des erreurs. Si vous choisissez de réutiliser l'un de ces codes dans une application de production, assurez-vous de gérer les erreurs et de tester entièrement tous les codes.

Assurez-vous que tout fonctionne dans l'application :

  1. Connectez-vous de manière anonyme à l'aide du bouton Connexion en haut à droite.
  2. Après vous être connecté, recherchez et ajoutez "NFLX", "SBUX" et "T" à la liste de suivi en cliquant sur le bouton Ajouter, en saisissant les lettres, puis en cliquant sur la ligne de résultat de recherche qui s'affiche en dessous.
  3. Pour supprimer une action de la liste de suivi, cliquez sur le x à la fin de la ligne.
  4. Suivez les mises à jour en temps réel du cours de l'action.
  5. Ouvrez les outils pour les développeurs Chrome, accédez à l'onglet Réseau, puis cochez les cases Désactiver le cache et Utiliser de grandes lignes de requête. L'option Désactiver le cache permet de s'assurer que les dernières modifications sont toujours prises en compte après une actualisation. L'option Utiliser les lignes de requêtes larges permet d'afficher à la fois la taille transmise et la taille de la ressource pour une ressource. Dans cet atelier de programmation, nous nous intéressons principalement à la taille de main.js.

48a096debb2aa940.png

  1. Chargez l'application dans différentes conditions de réseau à l'aide de la limitation simulée. Dans cet atelier de programmation, vous allez utiliser Slow 3G pour mesurer le temps de chargement, car c'est là qu'une taille de bundle plus petite est la plus utile.

4397cb2c1327089.png

Lancez-vous et commencez à migrer l'application vers la nouvelle API modulaire.

4. Utiliser les packages de compatibilité

Les packages de compatibilité vous permettent de passer à la nouvelle version du SDK sans modifier tout le code Firebase en même temps. Vous pouvez les migrer progressivement vers l'API modulaire.

Au cours de cette étape, vous allez mettre à niveau la bibliothèque Firebase de la version 8 vers la nouvelle version et modifier le code pour utiliser les packages de compatibilité. Dans les étapes suivantes, vous apprendrez à mettre à niveau uniquement le code Firebase Authentication pour utiliser d'abord l'API modulaire, puis à mettre à niveau le code Firestore.

À la fin de chaque étape, vous devriez pouvoir compiler et exécuter l'application sans problème, et constater une diminution de la taille du bundle à mesure que nous migrons chaque produit.

Obtenir le nouveau SDK

Recherchez la section des dépendances dans package.json et remplacez-la par ce qui suit :

package.json

"dependencies": {
    "firebase": "^9.0.0" 
}

Réinstaller les dépendances

Comme nous avons modifié la version de la dépendance, nous devons réexécuter npm install pour obtenir la nouvelle version de la dépendance.

Modifier les chemins d'importation

Les packages de compatibilité sont exposés sous le sous-module firebase/compat. Nous allons donc mettre à jour les chemins d'importation en conséquence :

  1. Accéder au fichier src/firebase.ts
  2. Remplacez les importations existantes par les suivantes :

src/firebase.ts

import firebase from 'firebase/compat/app'; 
import 'firebase/compat/auth'; 
import 'firebase/compat/firestore';

Vérifier que l'application fonctionne

  1. Exécutez npm run build pour recompiler l'application.
  2. Ouvrez http://localhost:8080 dans un nouvel onglet de votre navigateur ou actualisez l'onglet existant.
  3. Jouez avec l'application. Tout devrait encore fonctionner.

5. Mettre à niveau Auth pour utiliser l'API modulaire

Vous pouvez mettre à niveau les produits Firebase dans l'ordre de votre choix. Dans cet atelier de programmation, vous allez d'abord mettre à niveau Auth pour découvrir les concepts de base, car l'API Auth est relativement simple. La mise à niveau de Firestore est un peu plus complexe. Vous apprendrez comment procéder dans la prochaine section.

Mettre à jour l'initialisation de l'authentification

  1. Accéder au fichier src/firebase.ts
  2. Ajoutez l'importation suivante :

src/firebase.ts

import { initializeAuth, indexedDBLocalPersistence } from 'firebase/auth';
  1. Supprimer import ‘firebase/compat/auth'.
  2. Remplacez export const firebaseAuth = app.auth(); par :

src/firebase.ts

export const firebaseAuth = initializeAuth(app, { persistence: [indexedDBLocalPersistence] });
  1. Supprimez export type User = firebase.User; à la fin du fichier. User sera directement exporté dans src/auth.ts, que vous modifierez ensuite.

Mettre à jour le code d'autorisation

  1. Accéder au fichier src/auth.ts
  2. Ajoutez les importations suivantes en haut du fichier :

src/auth.ts

import { 
    signInAnonymously, 
    signOut,
    onAuthStateChanged,
    User
} from 'firebase/auth';
  1. Supprimez User de import { firebaseAuth, User } from './firebase';, car vous avez déjà importé User depuis ‘firebase/auth'..
  2. Mettez à jour les fonctions pour utiliser l'API modulaire.

Comme vous l'avez vu précédemment lorsque nous avons mis à jour l'instruction d'importation, les packages de la version 9 sont organisés autour de fonctions que vous pouvez importer, contrairement aux API de la version 8 qui sont basées sur un modèle d'espace de noms et de service enchaîné par des points. Cette nouvelle organisation du code permet d'éliminer le code inutilisé, car elle permet aux outils de compilation d'analyser le code utilisé et celui qui ne l'est pas.

Dans la version 9, les services sont transmis en tant que premier argument aux fonctions. Les services sont les objets que vous obtenez en initialisant un service Firebase, par exemple l'objet renvoyé par getAuth() ou initializeAuth(). Ils contiennent l'état d'un service Firebase spécifique, et la fonction utilise cet état pour effectuer ses tâches. Appliquons ce modèle pour implémenter les fonctions suivantes :

src/auth.ts

export function firebaseSignInAnonymously() { 
    return signInAnonymously(firebaseAuth); 
} 

export function firebaseSignOut() { 
    return signOut(firebaseAuth); 
} 

export function onUserChange(callback: (user: User | null) => void) { 
    return onAuthStateChanged(firebaseAuth, callback); 
} 

export { User } from 'firebase/auth';

Vérifier que l'application fonctionne

  1. Exécutez npm run build pour recompiler l'application.
  2. Ouvrez http://localhost:8080 dans un nouvel onglet de votre navigateur ou actualisez l'onglet existant.
  3. Jouez avec l'application. Tout devrait encore fonctionner.

Vérifier la taille du bundle

  1. Ouvrez les outils pour les développeurs Chrome.
  2. Accédez à l'onglet Réseau.
  3. Actualisez la page pour capturer les requêtes réseau.
  4. Recherchez main.js et vérifiez sa taille. Vous avez réduit la taille du bundle de 100 Ko (36 Ko compressé avec gzip), soit environ 22 %, en ne modifiant que quelques lignes de code. Le site se charge également 0,75 s plus rapidement avec une connexion 3G lente.

2e4eafaf66cd829b.png

6. Mettre à niveau l'application Firebase et Firestore pour utiliser l'API modulaire

Mettre à jour l'initialisation de Firebase

  1. Accéder au fichier src/firebase.ts.
  2. Remplacez import firebase from ‘firebase/compat/app'; par :

src/firebase.ts

import { initializeApp } from 'firebase/app';
  1. Remplacez const app = firebase.initializeApp({...}); par :

src/firebase.ts

const app = initializeApp({
    apiKey: "AIzaSyBnRKitQGBX0u8k4COtDTILYxCJuMf7xzE", 
    authDomain: "exchange-rates-adcf6.firebaseapp.com", 
    databaseURL: "https://exchange-rates-adcf6.firebaseio.com", 
    projectId: "exchange-rates-adcf6", 
    storageBucket: "exchange-rates-adcf6.firebasestorage.app", 
    messagingSenderId: "875614679042", 
    appId: "1:875614679042:web:5813c3e70a33e91ba0371b"
});

Mettre à jour l'initialisation de Firestore

  1. Dans le même fichier src/firebase.ts,, remplacez import 'firebase/compat/firestore'; par

src/firebase.ts

import { getFirestore } from 'firebase/firestore';
  1. Remplacez export const firestore = app.firestore(); par :

src/firebase.ts

export const firestore = getFirestore();
  1. Supprime toutes les lignes après "export const firestore = ..."

Mettre à jour les importations

  1. Ouvrir le fichier src/services.ts.
  2. Supprimez FirestoreFieldPath, FirestoreFieldValue et QuerySnapshot de l'importation. L'importation depuis './firebase' doit désormais se présenter comme suit :

src/services.ts

import { firestore } from './firebase';
  1. Importez les fonctions et les types que vous allez utiliser en haut du fichier :
    **src/services.ts**
import { 
    collection, 
    getDocs, 
    doc, 
    setDoc, 
    arrayUnion, 
    arrayRemove, 
    onSnapshot, 
    query, 
    where, 
    documentId, 
    QuerySnapshot
} from 'firebase/firestore';
  1. Créez une référence à la collection contenant tous les tickers :

src/services.ts

const tickersCollRef = collection(firestore, 'current');
  1. Utilisez getDocs() pour récupérer tous les documents de la collection :

src/services.ts

const tickers = await getDocs(tickersCollRef);

Consultez search() pour obtenir le code final.

Mettre à jour addToWatchList()

Utilisez doc() pour créer une référence de document à la liste de suivi de l'utilisateur, puis ajoutez-y un symbole boursier à l'aide de setDoc() avec arrayUnion() :

src/services.ts

export function addToWatchList(ticker: string, user: User) {
      const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
      return setDoc(watchlistRef, {
       tickers: arrayUnion(ticker)
   }, { merge: true });
}

Mettre à jour deleteFromWatchList()

De même, supprimez un symbole boursier de la liste de suivi d'un utilisateur à l'aide de setDoc() avec arrayRemove() :

src/services.ts

export function deleteFromWatchList(ticker: string, user: User) {
   const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
   return setDoc(watchlistRef, {
       tickers: arrayRemove(ticker)
   }, { merge: true });
}

Mettre à jour subscribeToTickerChanges()

  1. Utilisez doc() pour créer une référence de document à la liste de suivi de l'utilisateur, puis écoutez les modifications de la liste de suivi à l'aide de onSnapshot() :

src/services.ts

const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
const unsubscribe = onSnapshot(watchlistRef, snapshot => {
   /* subscribe to ticker price changes */
});
  1. Une fois que vous avez ajouté les codes boursiers à la liste de surveillance, utilisez query() pour créer une requête permettant d'extraire leurs prix et onSnapshot() pour écouter leurs variations de prix :

src/services.ts

const priceQuery = query(
    collection(firestore, 'current'),
    where(documentId(), 'in', tickers)
);
unsubscribePrevTickerChanges = onSnapshot(priceQuery, snapshot => {
               if (firstload) {
                   performance && performance.measure("initial-data-load");
                   firstload = false;
                   logPerformance();
               }
               const stocks = formatSDKStocks(snapshot);
               callback(stocks);
  });

Consultez subscribeToTickerChanges() pour l'implémentation complète.

Mettre à jour subscribeToAllTickerChanges()

Vous allez d'abord utiliser collection() pour créer une référence à la collection qui contient les prix de tous les tickers, puis utiliser onSnapshot() pour écouter les changements de prix :

src/services.ts

export function subscribeToAllTickerChanges(callback: TickerChangesCallBack) {
   const tickersCollRef = collection(firestore, 'current');
   return onSnapshot(tickersCollRef, snapshot => {
       if (firstload) {
           performance && performance.measure("initial-data-load");
           firstload = false;
           logPerformance();
       }
       const stocks = formatSDKStocks(snapshot);
       callback(stocks);
   });
}

Vérifier que l'application fonctionne

  1. Exécutez npm run build pour recompiler l'application.
  2. Ouvrez http://localhost:8080 dans un nouvel onglet de votre navigateur ou actualisez l'onglet existant.
  3. Jouez avec l'application. Tout devrait encore fonctionner.

Vérifier la taille du bundle

  1. Ouvrez les outils pour les développeurs Chrome.
  2. Accédez à l'onglet Réseau.
  3. Actualisez la page pour capturer les requêtes réseau.
  4. Recherchez main.js et vérifiez sa taille. Comparez-la à nouveau à la taille du bundle d'origine : nous avons réduit la taille du bundle de plus de 200 Ko (63,8 Ko compressé avec gzip), soit 50 % de moins, ce qui se traduit par un temps de chargement plus rapide de 1,3 s.

7660cdc574ee8571.png

7. Utiliser Firestore Lite pour accélérer le rendu initial des pages

Qu'est-ce que Firestore Lite ?

Le SDK Firestore offre une mise en cache complexe, un streaming en temps réel, un stockage persistant, une synchronisation hors connexion multi-onglets, des nouvelles tentatives, une concurrence optimiste et bien plus encore. Il est donc assez volumineux. Mais vous pouvez simplement vouloir obtenir les données une seule fois, sans avoir besoin des fonctionnalités avancées. Pour ces cas, Firestore a créé une solution simple et légère, un tout nouveau package : Firestore Lite.

Firestore Lite est particulièrement utile pour optimiser les performances du rendu initial de la page, lorsque vous avez uniquement besoin de savoir si un utilisateur est connecté ou non, puis de lire certaines données de Firestore pour les afficher.

Dans cette étape, vous allez apprendre à utiliser Firestore Lite pour réduire la taille du bundle afin d'accélérer le rendu initial de la page, puis à charger le SDK Firestore principal de manière dynamique pour vous abonner aux mises à jour en temps réel.

Vous allez refactoriser le code pour :

  1. Déplacez les services en temps réel dans un fichier distinct afin qu'ils puissent être chargés dynamiquement à l'aide de l'importation dynamique.
  2. Créez des fonctions pour utiliser Firestore Lite afin de récupérer la liste de suivi et les cours des actions.
  3. Utilisez les nouvelles fonctions Firestore Lite pour récupérer les données nécessaires au rendu initial de la page, puis chargez dynamiquement les services en temps réel pour écouter les mises à jour en temps réel.

Déplacer les services en temps réel vers un nouveau fichier

  1. Créez un fichier appelé src/services.realtime.ts..
  2. Déplacez les fonctions subscribeToTickerChanges() et subscribeToAllTickerChanges() de src/services.ts vers le nouveau fichier.
  3. Ajoutez les importations nécessaires en haut du nouveau fichier.

Vous devez encore apporter quelques modifications :

  1. Commencez par créer une instance Firestore à partir du SDK Firestore principal en haut du fichier à utiliser dans les fonctions. Vous ne pouvez pas importer l'instance Firestore depuis firebase.ts ici, car vous allez la remplacer par une instance Firestore Lite dans quelques étapes, qui ne sera utilisée que pour le rendu initial de la page.
  2. Ensuite, supprimez la variable firstload et le bloc "if" qu'elle protège. Leurs fonctionnalités seront déplacées vers les nouvelles fonctions que vous créerez à l'étape suivante.

src/services.realtime.ts

import { User } from './auth'
import { TickerChange } from './models';
import { collection, doc, onSnapshot, query, where, documentId, getFirestore } from 'firebase/firestore';
import { formatSDKStocks } from './services';

const firestore = getFirestore();
type TickerChangesCallBack = (changes: TickerChange[]) => void

export function subscribeToTickerChanges(user: User, callback: TickerChangesCallBack) {

   let unsubscribePrevTickerChanges: () => void;

   // Subscribe to watchlist changes. We will get an update whenever a ticker is added/deleted to the watchlist
   const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
   const unsubscribe = onSnapshot(watchlistRef, snapshot => {
       const doc = snapshot.data();
       const tickers = doc ? doc.tickers : [];

       if (unsubscribePrevTickerChanges) {
           unsubscribePrevTickerChanges();
       }

       if (tickers.length === 0) {
           callback([]);
       } else {
           // Query to get current price for tickers in the watchlist
           const priceQuery = query(
               collection(firestore, 'current'),
               where(documentId(), 'in', tickers)
           );

           // Subscribe to price changes for tickers in the watchlist
           unsubscribePrevTickerChanges = onSnapshot(priceQuery, snapshot => {
               const stocks = formatSDKStocks(snapshot);
               callback(stocks);
           });
       }
   });
   return () => {
       if (unsubscribePrevTickerChanges) {
           unsubscribePrevTickerChanges();
       }
       unsubscribe();
   };
}

export function subscribeToAllTickerChanges(callback: TickerChangesCallBack) {
   const tickersCollRef = collection(firestore, 'current');
   return onSnapshot(tickersCollRef, snapshot => {
       const stocks = formatSDKStocks(snapshot);
       callback(stocks);
   });
}

Utiliser Firestore Lite pour récupérer des données

  1. Ouvrir src/services.ts.
  2. Modifiez le chemin d'importation de ‘firebase/firestore' à ‘firebase/firestore/lite',, ajoutez getDoc et supprimez onSnapshot de la liste d'importation:.

src/services.ts

import { 
    collection, 
    getDocs, 
    doc, 
    setDoc, 
    arrayUnion, 
    arrayRemove,
//  onSnapshot, // firestore lite doesn't support realtime updates
    query, 
    where, 
    documentId, 
    QuerySnapshot, 
    getDoc // add this import
} from 'firebase/firestore/lite';
  1. Ajoutez des fonctions pour extraire les données nécessaires au rendu initial de la page à l'aide de Firestore Lite :

src/services.ts

export async function getTickerChanges(tickers: string[]): Promise<TickerChange[]> {

   if (tickers.length === 0) {
       return [];
   }

   const priceQuery = query(
       collection(firestore, 'current'),
       where(documentId(), 'in', tickers)
   );
   const snapshot = await getDocs(priceQuery);
   performance && performance.measure("initial-data-load");
   logPerformance();
   return formatSDKStocks(snapshot);
}

export async function getTickers(user: User): Promise<string[]> {
   const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
   const data =  (await getDoc(watchlistRef)).data();

   return data ? data.tickers : [];
}

export async function getAllTickerChanges(): Promise<TickerChange[]> {
   const tickersCollRef = collection(firestore, 'current');
   const snapshot = await getDocs(tickersCollRef);
   performance && performance.measure("initial-data-load");
   logPerformance();
   return formatSDKStocks(snapshot);
}
  1. Ouvrez src/firebase.ts et remplacez le chemin d'importation ‘firebase/firestore' par ‘firebase/firestore/lite':.

src/firebase.ts

import { getFirestore } from 'firebase/firestore/lite';

Faites le lien entre tous les éléments

  1. Ouvrir src/main.ts.
  2. Vous aurez besoin des fonctions que vous venez de créer pour récupérer les données pour le rendu initial de la page, ainsi que de quelques fonctions d'assistance pour gérer l'état de l'application. Modifiez maintenant les importations :

src/main.ts

import { renderLoginPage, renderUserPage } from './renderer';
import { getAllTickerChanges, getTickerChanges, getTickers } from './services';
import { onUserChange } from './auth';
import { getState, setRealtimeServicesLoaded, setUser } from './state';
import './styles.scss';
  1. Chargez src/services.realtime à l'aide d'une importation dynamique en haut du fichier. La variable loadRealtimeService est une promesse qui sera résolue avec les services en temps réel une fois le code chargé. Vous l'utiliserez ultérieurement pour vous abonner aux mises à jour en temps réel.

src/main.ts

const loadRealtimeService = import('./services.realtime');
loadRealtimeService.then(() => {
   setRealtimeServicesLoaded(true);
});
  1. Remplacez le rappel de onUserChange() par une fonction async afin de pouvoir utiliser await dans le corps de la fonction :

src/main.ts

onUserChange(async user => {
 // callback body
});
  1. Récupérez maintenant les données pour effectuer le rendu initial de la page à l'aide des nouvelles fonctions que nous avons créées à l'étape précédente.

Dans le rappel onUserChange(), recherchez la condition "if" dans laquelle un utilisateur est connecté, puis copiez et collez le code à l'intérieur de l'instruction "if" :

src/main.ts

onUserChange(async user => {
      // LEAVE THE EXISTING CODE UNCHANGED HERE
      ...

      if (user) {
       // REPLACE THESE LINES

       // user page
       setUser(user);

       // show loading screen in 500ms
       const timeoutId = setTimeout(() => {
           renderUserPage(user, {
               loading: true,
               tableData: []
           });
       }, 500);

       // get data once if realtime services haven't been loaded
       if (!getState().realtimeServicesLoaded) {
           const tickers = await getTickers(user);
           const tickerData = await getTickerChanges(tickers);
           clearTimeout(timeoutId);
           renderUserPage(user, { tableData: tickerData });
       }

       // subscribe to realtime updates once realtime services are loaded
       loadRealtimeService.then(({ subscribeToTickerChanges }) => {
           unsubscribeTickerChanges = subscribeToTickerChanges(user, stockData => {
               clearTimeout(timeoutId);
               renderUserPage(user, { tableData: stockData })
           });
       });
   } else {
     // DON'T EDIT THIS PART, YET   
   }
}
  1. Dans le bloc "else" où aucun utilisateur n'est connecté, récupérez les informations sur les prix de toutes les actions à l'aide de Firestore Lite, affichez la page, puis écoutez les changements de prix une fois les services en temps réel chargés :

src/main.ts

if (user) {
   // DON'T EDIT THIS PART, WHICH WE JUST CHANGED ABOVE
   ...
} else {
   // REPLACE THESE LINES

   // login page
   setUser(null);

   // show loading screen in 500ms
   const timeoutId = setTimeout(() => {
       renderLoginPage('Landing page', {
           loading: true,
           tableData: []
       });
   }, 500);

   // get data once if realtime services haven't been loaded
   if (!getState().realtimeServicesLoaded) {
       const tickerData = await getAllTickerChanges();
       clearTimeout(timeoutId);
       renderLoginPage('Landing page', { tableData: tickerData });
   }

   // subscribe to realtime updates once realtime services are loaded
   loadRealtimeService.then(({ subscribeToAllTickerChanges }) => {
       unsubscribeAllTickerChanges = subscribeToAllTickerChanges(stockData => {
           clearTimeout(timeoutId);
           renderLoginPage('Landing page', { tableData: stockData })
       });
   });
}

Consultez src/main.ts pour obtenir le code final.

Vérifier que l'application fonctionne

  1. Exécutez npm run build pour recompiler l'application.
  2. Ouvrez http://localhost:8080 dans un nouvel onglet de votre navigateur ou actualisez l'onglet existant.

Vérifier la taille du bundle

  1. Ouvrez les outils pour les développeurs Chrome.
  2. Accédez à l'onglet Réseau.
  3. Actualisez la page pour capturer les requêtes réseau.
  4. Recherchez main.js et vérifiez sa taille.
  5. Elle ne fait plus que 115 Ko (34,5 Ko compressée avec gzip). C'est 75 % de moins que la taille du bundle d'origine, qui était de 446 Ko(138 Ko compressé avec gzip). Le site se charge donc plus de deux secondes plus rapidement avec une connexion 3G, ce qui représente une amélioration considérable des performances et de l'expérience utilisateur.

9ea7398a8c8ef81b.png

8. Félicitations

Félicitations, vous avez réussi à mettre à niveau l'application, et à la rendre plus petite et plus rapide.

Vous avez utilisé les packages de compatibilité pour mettre à niveau l'application petit à petit, et vous avez utilisé Firestore Lite pour accélérer le rendu initial de la page, puis vous avez chargé dynamiquement le Firestore principal pour diffuser les changements de prix.

Vous avez également réduit la taille du bundle et amélioré son temps de chargement au cours de cet atelier de programmation :

main.js

taille de la ressource (ko)

Taille compressée (Ko)

temps de chargement (s) (sur une connexion 3G lente)

v8

446

138

4,92

Compatibilité avec la version 9

429

124

4.65

Authentification modulaire v9 uniquement

348

102

4.2

v9 entièrement modulaire

244

74,6

3.66

v9 entièrement modulaire + Firestore Lite

117

34.9

2.88

32a71bd5a774e035.png

Vous connaissez maintenant les étapes clés nécessaires pour mettre à niveau une application Web qui utilise le SDK JS Firebase v8 afin d'utiliser le nouveau SDK JS modulaire.

Complément d'informations

Documents de référence