Zwiększ możliwości swojej aplikacji internetowej, przechodząc na modułowy pakiet SDK Firebase JS

1. Zanim zaczniesz

Modułowy pakiet SDK Firebase JS to nowa wersja obecnego pakietu SDK JS, która zostanie opublikowana jako kolejna wersja główna. Umożliwia deweloperom wykluczanie nieużywanego kodu z pakietu Firebase JS SDK, aby tworzyć mniejsze pakiety i osiągać lepszą wydajność.

Najbardziej zauważalną różnicą w modułowym pakiecie SDK w JavaScript jest to, że funkcje są teraz uporządkowane w postaci niezależnych funkcji, które importujesz, a nie w jednej przestrzeni nazw firebase, która zawiera wszystko. Ten nowy sposób organizacji kodu umożliwia usuwanie nieużywanego kodu. Dowiesz się, jak uaktualnić dowolną aplikację, która obecnie korzysta z pakietu Firebase JS SDK w wersji 8, do nowej wersji modułowej.

Aby zapewnić płynny proces uaktualniania, udostępniamy zestaw pakietów zgodności. Z tego ćwiczenia z programowania dowiesz się, jak używać pakietów zgodności do przenoszenia aplikacji krok po kroku.

Co utworzysz

W tym laboratorium kodowania stopniowo przeniesiesz istniejącą aplikację internetową do śledzenia akcji, która korzysta z pakietu SDK w wersji 8, do nowego modułowego pakietu SDK w 3 etapach:

  • Uaktualnianie aplikacji w celu korzystania z pakietów zgodności
  • Stopniowe przechodzenie z pakietów zgodności na modułowy interfejs API
  • Aby jeszcze bardziej zwiększyć wydajność aplikacji, użyj Firestore Lite, czyli uproszczonej implementacji pakietu SDK Firestore.

2d351cb47b604ad7.png

Ten przewodnik skupia się na aktualizacji pakietu SDK Firebase. Inne koncepcje i bloki kodu zostały pominięte. Można je po prostu skopiować i wkleić.

Czego potrzebujesz

  • wybraną przeglądarkę, np. Chrome;
  • Wybrane IDE lub edytor tekstu, np. WebStorm, Atom, Sublime lub VS Code.
  • Menedżer pakietów npm, który zwykle jest dostarczany z Node.js
  • przykładowy kod z codelabu (instrukcje pobierania kodu znajdziesz w następnym kroku codelabu);

2. Pierwsze kroki

Pobierz kod

Wszystko, czego potrzebujesz do tego projektu, znajduje się w repozytorium Git. Aby rozpocząć, pobierz kod i otwórz go w ulubionym środowisku programistycznym.

Sklonuj repozytorium GitHub z poziomu wiersza poleceń:

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

Jeśli nie masz zainstalowanego narzędzia git, możesz pobrać repozytorium jako plik ZIP i rozpakować pobrany plik.

Importowanie aplikacji

  1. W IDE otwórz lub zaimportuj katalog codelab-modular-sdk.
  2. Uruchom polecenie npm install, aby zainstalować zależności wymagane do skompilowania i lokalnego uruchomienia aplikacji.
  3. Uruchom npm run build, aby skompilować aplikację.
  4. Uruchom npm run serve, aby uruchomić serwer WWW.
  5. Otwórz kartę przeglądarki z adresem http://localhost:8080.

71a8a7d47392e8f4.png

3. Ustalenie wartości odniesienia

Jaki jest Twój punkt początkowy?

Punktem wyjścia jest aplikacja do śledzenia akcji, która została zaprojektowana na potrzeby tego ćwiczenia. Kod został uproszczony, aby zilustrować koncepcje przedstawione w tych ćwiczeniach, i zawiera niewiele mechanizmów obsługi błędów. Jeśli zdecydujesz się użyć tego kodu w aplikacji produkcyjnej, pamiętaj, aby obsłużyć wszystkie błędy i dokładnie przetestować cały kod.

Sprawdź, czy wszystko działa w aplikacji:

  1. Zaloguj się anonimowo, klikając przycisk Zaloguj się w prawym górnym rogu.
  2. Po zalogowaniu się wyszukaj i dodaj do listy obserwacyjnej symbole „NFLX”, „SBUX” i „T”. Aby to zrobić, kliknij przycisk Dodaj, wpisz litery i kliknij wiersz wyniku wyszukiwania, który pojawi się poniżej.
  3. Aby usunąć akcje z listy obserwacyjnej, kliknij x na końcu wiersza.
  4. Obserwuj aktualizacje ceny akcji w czasie rzeczywistym.
  5. Otwórz Narzędzia deweloperskie w Chrome, przejdź na kartę Sieć i zaznacz opcje Wyłącz pamięć podręcznąUżywaj dużych wierszy żądań. Wyłączanie pamięci podręcznej sprawia, że po odświeżeniu zawsze otrzymujemy najnowsze zmiany, a Używaj dużych wierszy żądań powoduje, że w wierszu wyświetlany jest zarówno rozmiar przesyłany, jak i rozmiar zasobu. W tym laboratorium kodu interesuje nas głównie rozmiar main.js.

48a096debb2aa940.png

  1. Wczytaj aplikację w różnych warunkach sieciowych, korzystając z symulowanego ograniczania. W tym laboratorium będziesz używać wolnego połączenia 3G do pomiaru czasu wczytywania, ponieważ w tym przypadku mniejszy rozmiar pakietu jest najbardziej pomocny.

4397cb2c1327089.png

Teraz możesz zacząć migrację aplikacji do nowego modułowego interfejsu API.

4. Korzystanie z pakietów wymagających dostosowania

Pakiety zgodności umożliwiają przejście na nową wersję pakietu SDK bez jednoczesnej zmiany całego kodu Firebase. Możesz stopniowo uaktualniać je do modułowego interfejsu API.

W tym kroku uaktualnisz bibliotekę Firebase z wersji 8 do nowej wersji i zmienisz kod, aby używać pakietów zgodności. Z poniższych kroków dowiesz się, jak najpierw uaktualnić tylko kod Firebase Auth, aby korzystać z modułowego interfejsu API, a potem uaktualnić kod Firestore.

Po zakończeniu każdego kroku powinna być możliwość skompilowania i uruchomienia aplikacji bez błędów oraz zaobserwowania zmniejszenia rozmiaru pakietu w miarę przenoszenia poszczególnych produktów.

Pobieranie nowego pakietu SDK

Znajdź sekcję zależności w package.json i zastąp ją tym kodem:

package.json

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

Ponownie zainstaluj zależności

Ponieważ zmieniliśmy wersję zależności, musimy ponownie uruchomić npm install, aby uzyskać nową wersję zależności.

Zmienianie ścieżek importu

Pakiety zgodności są udostępniane w podmodule firebase/compat, więc odpowiednio zaktualizujemy ścieżki importu:

  1. Otwórz plik src/firebase.ts
  2. Zastąp istniejące instrukcje importu tymi:

src/firebase.ts

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

Sprawdzanie działania aplikacji

  1. Uruchom npm run build, aby ponownie utworzyć aplikację.
  2. Otwórz kartę przeglądarki z adresem http://localhost:8080 lub odśwież istniejącą kartę.
  3. Korzystaj z aplikacji. Wszystko powinno nadal działać.

5. Uaktualnianie uwierzytelniania w celu korzystania z modułowego interfejsu API

Produkty Firebase możesz uaktualniać w dowolnej kolejności. W tym ćwiczeniu z programowania najpierw zaktualizujesz Auth, aby poznać podstawowe pojęcia, ponieważ interfejs Auth API jest stosunkowo prosty. Uaktualnienie Firestore jest nieco bardziej skomplikowane. W następnej kolejności dowiesz się, jak to zrobić.

Zaktualizuj inicjowanie uwierzytelniania

  1. Otwórz plik src/firebase.ts
  2. Dodaj ten import:

src/firebase.ts

import { initializeAuth, indexedDBLocalPersistence } from 'firebase/auth';
  1. Usuń: import ‘firebase/compat/auth'.
  2. Zastąp export const firebaseAuth = app.auth(); tym tekstem:

src/firebase.ts

export const firebaseAuth = initializeAuth(app, { persistence: [indexedDBLocalPersistence] });
  1. Usuń export type User = firebase.User; na końcu pliku. User zostanie bezpośrednio wyeksportowany do src/auth.ts, który następnie zmienisz.

Zaktualizuj kod autoryzacji

  1. Otwórz plik src/auth.ts
  2. Dodaj na początku pliku te instrukcje importu:

src/auth.ts

import { 
    signInAnonymously, 
    signOut,
    onAuthStateChanged,
    User
} from 'firebase/auth';
  1. Usuń Userimport { firebaseAuth, User } from './firebase';, ponieważ User zostało już zaimportowane z ‘firebase/auth'.
  2. Zaktualizuj funkcje, aby korzystać z modułowego interfejsu API.

Jak już widzieliśmy wcześniej, gdy aktualizowaliśmy instrukcję importu, pakiety w wersji 9 są uporządkowane według funkcji, które można importować. W przeciwieństwie do interfejsów API w wersji 8, które są oparte na przestrzeni nazw połączonej kropkami i wzorcu usługi. To nowa organizacja kodu umożliwia usuwanie nieużywanego kodu, ponieważ pozwala narzędziom do kompilacji analizować, który kod jest używany, a który nie.

W wersji 9 usługi są przekazywane jako pierwszy argument funkcji. Usługi to obiekty uzyskane po zainicjowaniu usługi Firebase, np. obiekt zwrócony przez getAuth() lub initializeAuth(). Przechowują one stan konkretnej usługi Firebase, a funkcja używa tego stanu do wykonywania swoich zadań. Zastosujmy ten wzorzec, aby zaimplementować te funkcje:

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';

Sprawdź, czy aplikacja działa

  1. Uruchom npm run build, aby ponownie utworzyć aplikację.
  2. Otwórz kartę przeglądarki z adresem http://localhost:8080 lub odśwież istniejącą kartę.
  3. Korzystaj z aplikacji. Wszystko powinno nadal działać.

Sprawdzanie rozmiaru pakietu

  1. Otwórz Narzędzia deweloperskie w Chrome.
  2. Przejdź na kartę Sieć.
  3. Odśwież stronę, aby przechwycić żądania sieciowe.
  4. Znajdź plik main.js i sprawdź jego rozmiar. Zmniejszyliśmy rozmiar pakietu o 100 KB (36 KB po skompresowaniu), czyli o około 22%, zmieniając tylko kilka wierszy kodu. Strona wczytuje się też o 0,75 s szybciej przy wolnym połączeniu 3G.

2e4eafaf66cd829b.png

6. Uaktualnianie aplikacji Firebase i Firestore do korzystania z modułowego interfejsu API

Aktualizacja inicjowania Firebase

  1. Otwórz plik src/firebase.ts.
  2. Zastąp import firebase from ‘firebase/compat/app'; tym tekstem:

src/firebase.ts

import { initializeApp } from 'firebase/app';
  1. Zastąp const app = firebase.initializeApp({...}); tym tekstem:

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"
});

Aktualizowanie inicjowania Firestore

  1. W tym samym pliku src/firebase.ts, zastąp import 'firebase/compat/firestore'; wartością

src/firebase.ts

import { getFirestore } from 'firebase/firestore';
  1. Zastąp export const firestore = app.firestore(); tym tekstem:

src/firebase.ts

export const firestore = getFirestore();
  1. Usuń wszystkie wiersze po „export const firestore = ...

Aktualizowanie importów

  1. Otwórz plik src/services.ts.
  2. Usuń z importu kolumny FirestoreFieldPath, FirestoreFieldValueQuerySnapshot. Import z './firebase' powinien teraz wyglądać tak:

src/services.ts

import { firestore } from './firebase';
  1. Zaimportuj funkcje i typy, których będziesz używać, na początku pliku:
    **src/services.ts**
import { 
    collection, 
    getDocs, 
    doc, 
    setDoc, 
    arrayUnion, 
    arrayRemove, 
    onSnapshot, 
    query, 
    where, 
    documentId, 
    QuerySnapshot
} from 'firebase/firestore';
  1. Utwórz odwołanie do kolekcji, która zawiera wszystkie symbole giełdowe:

src/services.ts

const tickersCollRef = collection(firestore, 'current');
  1. Użyj getDocs(), aby pobrać wszystkie dokumenty z kolekcji:

src/services.ts

const tickers = await getDocs(tickersCollRef);

Gotowy kod znajdziesz w sekcji search().

Aktualizacja funkcji addToWatchList()

Użyj doc(), aby utworzyć odwołanie do dokumentu na liście obserwowanych użytkownika, a następnie dodaj do niego symbol giełdowy za pomocą setDoc()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 });
}

Aktualizacja funkcji deleteFromWatchList()

Podobnie możesz usunąć symbol z listy Do obejrzenia użytkownika za pomocą żądania setDoc() z parametrem 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 });
}

Aktualizacja funkcji subscribeToTickerChanges()

  1. Użyj doc(), aby najpierw utworzyć odwołanie do dokumentu na liście obserwowanych użytkownika, a następnie nasłuchiwać zmian na liście obserwowanych za pomocą onSnapshot():

src/services.ts

const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
const unsubscribe = onSnapshot(watchlistRef, snapshot => {
   /* subscribe to ticker price changes */
});
  1. Gdy dodasz symbole do listy obserwacyjnej, użyj ikony query(), aby utworzyć zapytanie o pobranie ich cen, a ikony onSnapshot(), aby śledzić zmiany cen:

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);
  });

Pełną implementację znajdziesz w artykule subscribeToTickerChanges().

Aktualizacja funkcji subscribeToAllTickerChanges()

Najpierw użyj collection(), aby utworzyć odwołanie do kolekcji, która zawiera ceny wszystkich symboli giełdowych, a potem użyj onSnapshot(), aby nasłuchiwać zmian cen:

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);
   });
}

Sprawdź, czy aplikacja działa

  1. Uruchom npm run build, aby ponownie utworzyć aplikację.
  2. Otwórz kartę przeglądarki z adresem http://localhost:8080 lub odśwież istniejącą kartę.
  3. Korzystaj z aplikacji. Wszystko powinno nadal działać.

Sprawdzanie rozmiaru pakietu

  1. Otwórz Narzędzia deweloperskie w Chrome.
  2. Przejdź na kartę Sieć.
  3. Odśwież stronę, aby przechwycić żądania sieciowe.
  4. Poszukaj ikony main.js i sprawdź jej rozmiar. Porównaj go ponownie z rozmiarem oryginalnego pakietu – zmniejszyliśmy go o ponad 200 KB (63,8 KB po skompresowaniu), czyli o 50%. Przekłada się to na 1,3 s krótszy czas wczytywania.

7660cdc574ee8571.png

7. Używanie Firestore Lite do przyspieszenia początkowego renderowania strony

Co to jest Firestore Lite?

Pakiet SDK Firestore oferuje złożone buforowanie, przesyłanie strumieniowe w czasie rzeczywistym, trwałe przechowywanie, synchronizację offline w wielu kartach, ponawianie prób, optymistyczne współbieżność i wiele innych funkcji, dlatego jest dość duży. Możesz jednak po prostu chcieć pobrać dane jednorazowo bez korzystania z funkcji zaawansowanych. W takich przypadkach Firestore oferuje proste i lekkie rozwiązanie – zupełnie nowy pakiet Firestore Lite.

Świetnym przykładem zastosowania Firestore Lite jest optymalizacja wydajności wstępnego renderowania strony, gdy musisz tylko wiedzieć, czy użytkownik jest zalogowany, a następnie odczytać z Firestore niektóre dane do wyświetlenia.

Z tego kroku dowiesz się, jak używać Firestore Lite, aby zmniejszyć rozmiar pakietu i przyspieszyć początkowe renderowanie strony, a następnie dynamicznie wczytywać główny pakiet SDK Firestore, aby subskrybować aktualizacje w czasie rzeczywistym.

Przeprowadzisz refaktoryzację kodu, aby:

  1. Przenieś usługi czasu rzeczywistego do osobnego pliku, aby można było je dynamicznie wczytywać za pomocą importu dynamicznego.
  2. Utwórz nowe funkcje, aby używać Firestore Lite do pobierania listy obserwowanych i cen akcji.
  3. Użyj nowych funkcji Firestore Lite, aby pobrać dane do wstępnego renderowania strony, a następnie dynamicznie wczytać usługi czasu rzeczywistego, aby nasłuchiwać aktualizacji w czasie rzeczywistym.

Przenoszenie usług działających w czasie rzeczywistym do nowego pliku

  1. Utwórz nowy plik o nazwie src/services.realtime.ts..
  2. Przenieś funkcje subscribeToTickerChanges()subscribeToAllTickerChanges() z pliku src/services.ts do nowego pliku.
  3. Dodaj niezbędne instrukcje importu na początku nowego pliku.

Musisz jeszcze wprowadzić kilka zmian:

  1. Najpierw utwórz instancję Firestore z głównego pakietu SDK Firestore u góry pliku, który ma być używany w funkcjach. Nie możesz tutaj zaimportować instancji Firestore z firebase.ts, ponieważ za kilka kroków zmienisz ją w instancję Firestore Lite, która będzie używana tylko do początkowego renderowania strony.
  2. Po drugie, usuń zmienną firstload i blok if, który jest przez nią chroniony. Ich funkcje zostaną przeniesione do nowych funkcji, które utworzysz w następnym kroku.

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);
   });
}

Pobieranie danych za pomocą Firestore Lite

  1. Otwórz: src/services.ts.
  2. Zmień ścieżkę importu z ‘firebase/firestore' na ‘firebase/firestore/lite',, dodaj getDoc i usuń onSnapshot z listy importu:

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. Dodaj funkcje pobierania danych potrzebnych do wstępnego renderowania strony za pomocą 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. Otwórz src/firebase.ts i zmień ścieżkę importu z ‘firebase/firestore' na ‘firebase/firestore/lite':.

src/firebase.ts

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

Połącz wszystkie elementy

  1. Otwórz: src/main.ts.
  2. Nowo utworzone funkcje będą potrzebne do pobierania danych na potrzeby wstępnego renderowania strony, a kilka funkcji pomocniczych do zarządzania stanem aplikacji. Teraz zaktualizuj importy:

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. Załaduj src/services.realtime za pomocą importu dynamicznego u góry pliku. Zmienna loadRealtimeService to obietnica, która zostanie spełniona w przypadku usług w czasie rzeczywistym po załadowaniu kodu. Będzie Ci potrzebny później do subskrybowania aktualizacji w czasie rzeczywistym.

src/main.ts

const loadRealtimeService = import('./services.realtime');
loadRealtimeService.then(() => {
   setRealtimeServicesLoaded(true);
});
  1. Zmień wywołanie zwrotne funkcji onUserChange() na funkcję async, aby w treści funkcji można było używać await:

src/main.ts

onUserChange(async user => {
 // callback body
});
  1. Teraz pobierz dane, aby wyrenderować początkową stronę za pomocą nowych funkcji utworzonych w poprzednim kroku.

W wywołaniu zwrotnym onUserChange() znajdź warunek if, w którym użytkownik jest zalogowany, i skopiuj oraz wklej kod wewnątrz instrukcji 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. W bloku else, w którym żaden użytkownik nie jest zalogowany, pobierz informacje o cenach wszystkich akcji za pomocą Firestore Lite, wyrenderuj stronę, a następnie nasłuchuj zmian cen po załadowaniu usług w czasie rzeczywistym:

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 })
       });
   });
}

Gotowy kod znajdziesz w pliku src/main.ts.

Sprawdź, czy aplikacja działa

  1. Uruchom npm run build, aby ponownie utworzyć aplikację.
  2. Otwórz kartę przeglądarki z adresem http://localhost:8080 lub odśwież istniejącą kartę.

Sprawdzanie rozmiaru pakietu

  1. Otwórz Narzędzia deweloperskie w Chrome.
  2. Przejdź na kartę Sieć.
  3. Odśwież stronę, aby przechwycić żądania sieciowe
  4. Poszukaj ikony main.js i sprawdź jej rozmiar.
  5. Teraz ma tylko 115 KB (34,5 KB po skompresowaniu). To o 75% mniej niż pierwotny rozmiar pakietu, który wynosił 446 KB(138 KB po skompresowaniu). Dzięki temu witryna wczytuje się o ponad 2 sekundy szybciej przy połączeniu 3G, co znacznie poprawia wydajność i wygodę użytkowników.

9ea7398a8c8ef81b.png

8. Gratulacje

Udało Ci się uaktualnić aplikację, dzięki czemu jest mniejsza i szybsza.

Do uaktualniania aplikacji krok po kroku używasz pakietów zgodności, a do przyspieszenia początkowego renderowania strony – Firestore Lite. Następnie dynamicznie wczytujesz główną usługę Firestore, aby przesyłać strumieniowo zmiany cen.

W trakcie tego kursu zmniejszyliśmy też rozmiar pakietu i skróciliśmy czas jego ładowania:

main.js

rozmiar zasobu (KB)

rozmiar po skompresowaniu (KB)

czas wczytywania (s) (przy wolnym połączeniu 3G);

v8

446

138

4,92

v9 compat

429

124

4,65

Tylko modułowe uwierzytelnianie w wersji 9

348

102

4.2

v9 fully modular

244

74,6

3,66

v9 fully modular + Firestore lite

117

34,9

2,88

32a71bd5a774e035.png

Znasz już najważniejsze kroki, które należy wykonać, aby uaktualnić aplikację internetową korzystającą z pakietu Firebase JS SDK w wersji 8 do korzystania z nowego modułowego pakietu JS SDK.

Więcej informacji

Dokumentacja