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

1. Avant de commencer

Le SDK Firebase JS modulaire 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 afin de créer des bundles plus petits et d'obtenir de meilleures performances.

La différence la plus notable du SDK JS modulaire est que les fonctionnalités sont désormais organisées en fonctions flottantes que vous allez importer, et non dans un seul espace de noms firebase qui inclut tout. Cette nouvelle façon d'organiser le code permet le "tree shaking". Vous allez apprendre à mettre à niveau toute application qui utilise actuellement le SDK JS Firebase v8 vers le nouveau SDK modulaire.

Pour faciliter la mise à niveau, un ensemble de packages de compatibilité est fourni. Dans cet atelier de programmation, vous allez apprendre à utiliser les packages de compatibilité pour porter l'application par parties.

Objectifs de l'atelier

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

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

2d351cb47b604ad7.png

Cet atelier de programmation porte sur la mise à niveau du SDK Firebase. D'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 paquets npm, 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. Dans votre IDE, ouvrez ou importez le répertoire codelab-modular-sdk.
  2. Exécutez npm install pour installer les dépendances requises pour créer et exécuter l'application en local.
  3. Exécutez npm run build pour compiler l'application.
  4. Exécuter 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 surveillance 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 tout le code.

Assurez-vous que tout fonctionne dans l'application:

  1. Connectez-vous de manière anonyme à l'aide du bouton Se connecter en haut à droite.
  2. Après vous être connecté, recherchez et ajoutez "NFLX", "SBUX" et "T" à la liste de surveillance en cliquant sur le bouton Ajouter, en saisissant les lettres, puis en cliquant sur la ligne de résultats de recherche qui s'affiche en dessous.
  3. Pour supprimer une action de la liste de surveillance, cliquez sur la croix X à la fin de la ligne.
  4. Suivez les fluctuations du cours en temps réel.
  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. Désactiver le cache permet de toujours obtenir les dernières modifications après un actualisation, et Utiliser les lignes de requêtes larges permet à la ligne d'afficher à la fois la taille transmise et la taille de la 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 réseau à l'aide d'une limitation de bande passante simulée. Dans cet atelier de programmation, vous allez utiliser la connexion 3G lente pour mesurer le temps de chargement, car c'est là que la taille de lot 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 l'ensemble du code Firebase en une seule fois. Vous pouvez les migrer vers l'API modulaire progressivement.

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

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

Obtenir le nouveau SDK

Recherchez la section "dépendances" dans le fichier 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 importations 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 un nouvel onglet de votre navigateur et accédez à http://localhost:8080 , ou actualisez l'onglet existant.
  3. Testez l'application. Tout devrait continuer à fonctionner.

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

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

Mise à jour de 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 allez modifier 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 qu'elles utilisent l'API modulaire.

Comme vous l'avez déjà 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 espace de noms et un modèle de service en chaîne de points. C'est cette nouvelle organisation du code qui permet de supprimer 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 particulier, et la fonction utilise cet état pour effectuer ses tâches. Appliquez 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 un nouvel onglet de votre navigateur et accédez à http://localhost:8080 , ou actualisez l'onglet existant.
  3. Testez l'application. Tout devrait continuer à fonctionner.

Vérifier la taille du lot

  1. Ouvrez les Outils pour les développeurs Chrome.
  2. Accédez à l'onglet Network (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és 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. Supprimer 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 à partir de './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 codes boursiers:

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 finalisé.

Modifier addToWatchList()

Utilisez doc() pour créer une référence de document vers la liste de lecture de l'utilisateur, puis ajoutez-y un code 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 });
}

Mise à jour de deleteFromWatchList()

De même, supprimez un code boursier de la liste de surveillance de l'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 });
}

Modifier subscribeToTickerChanges()

  1. Utilisez doc() pour créer d'abord une référence de document à la liste de lecture de l'utilisateur, puis écoutez les modifications apportées à la liste de lecture à 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 les codes boursiers ajoutés à la liste de surveillance, utilisez query() pour créer une requête permettant d'extraire leurs prix et onSnapshot() pour écouter leurs changements 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);
  });

Pour obtenir l'implémentation complète, consultez subscribeToTickerChanges().

Modifier subscribeToAllTickerChanges()

Vous devez d'abord utiliser collection() pour créer une référence à la collection contenant les prix de tous les codes boursiers, puis 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 un nouvel onglet de votre navigateur et accédez à http://localhost:8080 , ou actualisez l'onglet existant.
  3. Testez l'application. Tout devrait continuer à fonctionner.

Vérifier la taille du lot

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

7660cdc574ee8571.png

7. Utiliser Firestore Lite pour accélérer le rendu initial de la page

Qu'est-ce que Firestore Lite ?

Le SDK Firestore offre un cache complexe, un streaming en temps réel, un stockage persistant, une synchronisation hors connexion multi-onglet, des nouvelles tentatives, une concurrence optimiste, et bien plus encore. Il est donc assez volumineux. Toutefois, vous pouvez simplement 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 de la page initiale. Il vous suffit de savoir si un utilisateur est connecté ou non, puis de lire des 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 dynamiquement le SDK Firestore principal 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 vers 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 surveillance 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 nommé 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 à partir de firebase.ts ici, car vous allez la remplacer par une instance Firestore Lite en 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 transférées vers de 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 extraire des données

  1. Ouvrir src/services.ts.
  2. Modification du chemin d'importation de ‘firebase/firestore' à ‘firebase/firestore/lite',, ajout de getDoc et suppression de 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, puis remplacez le chemin d'importation ‘firebase/firestore' par ‘firebase/firestore/lite':.

src/firebase.ts

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

Mettre tout en lien

  1. Ouvrir src/main.ts.
  2. Vous aurez besoin des fonctions nouvellement créées pour extraire les données du rendu initial de la page, ainsi que de quelques fonctions d'assistance pour gérer l'état de l'application. Modifiez donc 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 plus tard 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 de la page initiale à l'aide des nouvelles fonctions que nous avons créées à l'étape précédente.

Dans le rappel onUserChange(), recherchez la condition "si" où un utilisateur est connecté, puis copiez et collez le code dans l'instruction "si" :

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 tous les stocks à 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 finalisé.

Vérifier que l'application fonctionne

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

Vérifier la taille du lot

  1. Ouvrez les Outils pour les développeurs Chrome.
  2. Accédez à l'onglet Network (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é avec gzip). Cela représente 75% de moins que la taille d'origine du bundle, qui était de 446 ko(138 ko compressés avec gzip). Le chargement du site est ainsi plus rapide de plus de deux secondes en connexion 3G, ce qui représente une amélioration significative des performances et de l'expérience utilisateur.

9ea7398a8c8ef81b.png

8. Félicitations

Félicitations, vous avez bien mis à niveau l'application, et l'avez rendue plus petite et plus rapide.

Vous avez utilisé les packages de compatibilité pour mettre à niveau l'application par parties, Firestore Lite pour accélérer le rendu initial de la page, puis chargé dynamiquement Firestore principal pour diffuser les modifications 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 3G lente)

v8

446

138

4,92

Compatibilité avec la version 9

429

124

4.65

Auth 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 savez maintenant quelles sont les étapes clés à suivre 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