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

1. Avant de commencer

Le SDK modulaire Firebase JS 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 Firebase JS 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 en fonctions flottantes libres que vous importerez, par opposition à un seul espace de noms firebase qui inclut tout. Cette nouvelle façon d'organiser le code permet de secouer l'arborescence, et vous apprendrez comment mettre à niveau n'importe quelle application utilisant actuellement le SDK Firebase JS v8 vers la nouvelle version modulaire.

Pour assurer un processus de mise à niveau fluide, un ensemble de packages de compatibilité est fourni. Dans cet atelier de programmation, vous apprendrez à utiliser les packages de compatibilité pour porter l'application pièce par pièce.

Ce que vous construirez

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

  • Mettez à niveau l'application pour utiliser les packages de compatibilité
  • Mettez à niveau l'application des packages de compatibilité vers l'API modulaire pièce par pièce
  • Utilisez Firestore Lite, une implémentation légère du SDK Firestore, pour améliorer encore les performances de l'application

2d351cb47b604ad7.png

Cet atelier de programmation se concentre sur la mise à niveau du SDK Firebase. D'autres concepts et blocs de code sont passés sous silence et vous sont fournis pour que vous puissiez simplement les copier et les coller.

Ce dont vous aurez besoin

  • 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
  • Exemple de code de l'atelier de programmation (consultez l'étape suivante de l'atelier de programmation pour savoir comment obtenir le code.)

2. Préparez-vous

Obtenez le code

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

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

Alternativement, si git n'est pas installé, vous pouvez télécharger le référentiel sous forme de fichier ZIP et décompresser le fichier zip téléchargé.

Importer l'application

  1. À l’aide de 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 localement.
  3. Exécutez npm run build pour créer l'application.
  4. Exécutez npm run serve pour démarrer le serveur Web
  5. Ouvrez un onglet de navigateur sur http://localhost:8080

71a8a7d47392e8f4.png

3. Établir une référence

Quel est votre point de départ ?

Votre point de départ est une application de liste de surveillance des actions conçue pour cet atelier de programmation. Le code a été simplifié pour illustrer les concepts de cet atelier de programmation, et il comporte 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 toutes 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 en utilisant le bouton de connexion dans le coin supérieur droit.
  2. Après vous être connecté, recherchez et ajoutez « NFLX », « SBUX » et « T » à la liste de surveillance en cliquant sur le bouton Ajouter , en tapant les lettres et en cliquant sur la ligne de résultats de recherche qui apparaît ci-dessous.
  3. Supprimez une action de la liste de surveillance en cliquant sur le x à la fin de la ligne.
  4. Regardez les mises à jour en temps réel du cours de l'action.
  5. Ouvrez Chrome DevTools, accédez à l'onglet Réseau et cochez Disable cache et Use large request rows . La désactivation du cache garantit que nous obtenons toujours les dernières modifications après une actualisation et l'utilisation de lignes de requêtes volumineuses permet à la ligne 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 d'une limitation simulée. Vous utiliserez Slow 3G pour mesurer le temps de chargement dans cet atelier de programmation, car c'est là qu'une taille de bundle plus petite est la plus utile.

4397cb2c1327089.png

Maintenant, lancez-vous et commencez à migrer l'application vers la nouvelle API modulaire.

4. Utilisez 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 mettre à niveau progressivement vers l'API modulaire.

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

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

Obtenez le nouveau SDK

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

package.json

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

Réinstaller les dépendances

Puisque 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 mettrons donc à jour les chemins d'importation en conséquence :

  1. Allez dans le 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 reconstruire l'application.
  2. Ouvrez un onglet de navigateur sur http://localhost:8080 ou actualisez l'onglet existant.
  3. Jouez avec l'application. Tout devrait toujours fonctionner.

5. Mettez à 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 et vous apprendrez comment procéder ensuite.

Mettre à jour l'initialisation de l'authentification

  1. Allez dans le fichier src/firebase.ts
  2. Ajoutez l'importation suivante :

src/firebase.ts

import { initializeAuth, indexedDBLocalPersistence } from 'firebase/auth';
  1. Supprimez import 'firebase/compat/auth'.
  2. Remplacer export const firebaseAuth = app.auth(); avec:

src/firebase.ts

export const firebaseAuth = initializeAuth(app, { persistence: [indexedDBLocalPersistence] });
  1. Supprimer 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'authentification

  1. Allez dans le 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. Supprimer User de import { firebaseAuth, User } from './firebase'; puisque vous avez déjà importé User depuis 'firebase/auth'.
  2. Mettez à jour les fonctions pour utiliser 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 secouer l'arborescence du code inutilisé, car elle permet aux outils de construction d'analyser quel code est utilisé et ce qui ne l'est pas.

En version 9, les services sont passés en 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 détiennent l'état d'un service Firebase particulier et la fonction utilise l'é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 reconstruire l'application.
  2. Ouvrez un onglet de navigateur sur http://localhost:8080 ou actualisez l'onglet existant
  3. Jouez avec l'application. Tout devrait toujours fonctionner.

Vérifier la taille du paquet

  1. Ouvrez les outils de développement Chrome.
  2. Passez à 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és), soit environ 22 % de moins en modifiant seulement quelques lignes de code ! Le site se charge également 0,75 s plus rapidement sur une connexion 3G lente.

2e4eafaf66cd829b.png

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

Mettre à jour l'initialisation de Firebase

  1. Accédez au fichier src/firebase.ts.
  2. Remplacer import firebase from 'firebase/compat/app'; avec:

src/firebase.ts

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

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.appspot.com", 
    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'; avec

src/firebase.ts

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

src/firebase.ts

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

Mettre à jour les importations

  1. Ouvrez le fichier src/services.ts.
  2. Supprimez FirestoreFieldPath , FirestoreFieldValue et QuerySnapshot de l'importation. L'importation depuis './firebase' devrait maintenant ressembler à ceci :

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 qui contient 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);

Voir search() pour le code terminé.

Mettre à jour addToWatchList()

Utilisez doc() pour créer une référence de document à la liste de surveillance de l'utilisateur, puis ajoutez-y un ticker en utilisant 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 ticker de la liste de surveillance de l'utilisateur en utilisant 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 d'abord doc() pour créer une référence de document à la liste de surveillance de l'utilisateur, puis écoutez les modifications de la liste de surveillance à 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 les tickers dans la liste de surveillance, utilisez query() pour créer une requête pour récupérer leurs prix et utilisez 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);
  });

Voir SubscribeToTickerChanges() pour l'implémentation complète.

Mettre à jour SubscribeToAllTickerChanges()

Vous utiliserez d’abord collection() pour créer une référence à la collection qui contient les prix de tous les tickers, puis utiliserez 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 reconstruire l'application.
  2. Ouvrez un onglet de navigateur sur http://localhost:8080 ou actualisez l'onglet existant
  3. Jouez avec l'application. Tout devrait toujours fonctionner.

Vérifier la taille du paquet

  1. Ouvrez les outils de développement Chrome.
  2. Passez à 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-le à nouveau à la taille du bundle d'origine : nous avons réduit la taille du bundle de plus de 200 Ko (63,8 Ko gzippés), soit 50 % plus petit, ce qui se traduit par un temps de chargement 1,3 seconde plus rapide !

7660cdc574ee8571.png

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

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 ligne multi-onglets, des tentatives, une concurrence optimiste et bien plus encore, et est donc assez volumineux. Mais vous souhaiterez peut-être simplement obtenir les données une seule fois, sans avoir besoin d’aucune des fonctionnalités avancées. Pour ces cas, Firestore a créé une solution simple et légère, un tout nouveau package : Firestore Lite.

Un excellent cas d'utilisation de Firestore Lite consiste à optimiser les performances du rendu initial de la page, où il vous suffit de savoir si un utilisateur est connecté ou non, puis de lire certaines données de Firetore pour les afficher.

Dans cette étape, vous apprendrez à 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 principal de Firestore 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 séparé afin qu'ils puissent être chargés dynamiquement à l'aide de l'importation dynamique.
  2. Créez de nouvelles fonctions pour utiliser Firestore Lite pour 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 afin d'effectuer le 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 nouveau 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 ici :

  1. Tout d'abord, créez 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 changer en instance Firestore Lite en quelques étapes, qui ne sera utilisée que pour le rendu initial de la page.
  2. Deuxièmement, débarrassez-vous de la variable firstload et du bloc if qu'elle garde. Leurs fonctionnalités seront déplacé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);
   });
}

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

  1. Ouvrez 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 récupérer 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 modifiez le chemin d'importation de 'firebase/firestore' à 'firebase/firestore/lite':

src/firebase.ts

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

Attachez-les tous ensemble

  1. Ouvrez src/main.ts.
  2. Vous aurez besoin des fonctions nouvellement créées 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. Alors maintenant, mettez à jour 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 se résoudra 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 que nous puissions 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 dans 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 })
       });
   });
}

Voir src/main.ts pour le code terminé.

Vérifier que l'application fonctionne

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

Vérifier la taille du paquet

  1. Ouvrez les outils de développement Chrome.
  2. Passez à 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. Maintenant, il ne fait que 115 Ko (34,5 Ko compressés). C'est 75 % plus petit que la taille du bundle d'origine qui était de 446 Ko (138 Ko compressés) ! En conséquence, le site se charge plus de 2 secondes plus rapidement sur une connexion 3G - une grande amélioration 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 compatibles pour mettre à niveau l'application pièce par pièce, et vous avez utilisé Firestore Lite pour accélérer le rendu initial de la page, puis charger dynamiquement le 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) (au-dessus de 3 g lents)

v8

446

138

4,92

compatibilité v9

429

124

4,65

v9 uniquement authentification modulaire

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 requises pour mettre à niveau une application Web qui utilise le SDK Firebase JS v8 afin d'utiliser le nouveau SDK JS modulaire.

Lectures complémentaires

Documents de référence