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 stanowi przeredagowanie istniejącego pakietu SDK JS i zostanie udostępniony jako następna wersja główna. Umożliwia programistom wykluczanie nieużywanego kodu z pakietu Firebase JS SDK, co pozwala tworzyć mniejsze pakiety i zwiększać wydajność.

Najbardziej zauważalną różnica w modułowym pakiecie SDK JS polega na tym, że funkcje są teraz zorganizowane w ramach importowanych funkcji swobodnej, a nie w pojedynczej przestrzeni nazw firebase, która zawiera wszystko. Ten nowy sposób organizacji kodu umożliwia potrząsanie drzewami. Dowiesz się, jak uaktualnić dowolną aplikację, która obecnie korzysta z pakietu Firebase JS SDK w wersji 8, do nowej, modułowej wersji.

Aby proces uaktualniania przebiegł sprawnie, dostępny jest zestaw pakietów zgodności. Z tego ćwiczenia w Codelabs dowiesz się, jak używać pakietów zgodności do przenoszenia poszczególnych aplikacji.

Co utworzysz

W ramach tego ćwiczenia w programie będziesz stopniowo przenosić dotychczasową aplikację internetową z bankowej listy obserwowanych notowań, która korzysta z pakietu SDK JS w wersji 8, do nowego modułowego pakietu SDK JS w 3 etapach:

  • Uaktualnij aplikację, aby móc używać pakietów zgodności
  • Uaktualnij aplikację z pakietów zgodności do modułowego interfejsu API
  • Użyj Firestore Lite, czyli uproszczonej implementacji pakietu SDK Firestore, aby jeszcze bardziej zwiększyć wydajność aplikacji

2D351cb47b604ad7.png

To ćwiczenia w programie skupiają się na uaktualnieniu pakietu SDK Firebase. Inne koncepcje i bloki kodu zostały zamaskowane. Można je po prostu skopiować i wkleić.

Czego potrzebujesz

  • wybraną przeglądarkę, np. Chrome;
  • wybrany edytor IDE/tekst, taki jak WebStorm, Atom, Sublime lub VS Code;
  • menedżer pakietów npm, który zwykle zawiera środowisko Node.js;
  • Przykładowy kod z tej ćwiczeń (aby dowiedzieć się, jak pobrać kod, zapoznaj się z następnym krokiem tej ćwiczenia)

2. Konfiguracja

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.

Skopiuj repozytorium GitHub ćwiczenia z programowania za pomocą wiersza poleceń:

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

Jeśli nie masz zainstalowanej aplikacji git, możesz pobrać repozytorium jako plik ZIP i rozpakować pobrany plik ZIP.

Importowanie aplikacji

  1. Używając swojego IDE, otwórz lub zaimportuj katalog codelab-modular-sdk.
  2. Uruchom npm install, aby zainstalować zależności wymagane do kompilowania i uruchamiania aplikacji lokalnie.
  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. Określ punkt odniesienia

Od czego chcesz zacząć?

Na początek możesz wykorzystać notowania giełdowe aplikacji do listy obserwowanych notowań stworzone na potrzeby tego ćwiczenia z programowania. Kod został uproszczony, aby ilustrować koncepcje tego ćwiczenia z programowania, i nie wymaga dużej obsługi błędów. Jeśli zdecydujesz się na ponowne użycie tego kodu w aplikacji produkcyjnej, pamiętaj, by naprawić błędy i w pełni przetestować cały kod.

Sprawdź, czy wszystko działa w aplikacji:

  1. Zaloguj się anonimowo za pomocą przycisku logowania w prawym górnym rogu.
  2. Po zalogowaniu się wyszukaj i dodaj „NFLX”, „SBUX” i „T” pojawi się na liście obserwowanych notowań. Aby to zrobić, kliknij przycisk Dodaj, wpisz litery i kliknij wiersz wyników wyszukiwania widoczny poniżej.
  3. Usunąć notowanie z listy obserwowanych notowań, klikając x na końcu wiersza.
  4. Obserwuj zmiany kursu akcji w czasie rzeczywistym.
  5. Otwórz Narzędzia deweloperskie w Chrome, przejdź na kartę Sieć i zaznacz Wyłącz pamięć podręczną oraz Użyj dużych wierszy żądań. Opcja Wyłącz pamięć podręczną zapewnia, że po odświeżeniu zawsze pobieramy najnowsze zmiany, a opcja Użyj dużych wierszy żądania powoduje, że wiersz wyświetla zarówno rozmiar przesyłanych danych, jak i rozmiar zasobu zasobu. W tym ćwiczeniu z programowania interesuje nas głównie rozmiar main.js.

48a096debb2aa940.png

  1. Wczytywanie aplikacji w różnych warunkach sieciowych za pomocą symulowanego ograniczania. W ramach tego ćwiczenia z programowania zmierzysz czas wczytywania przy użyciu wolnej sieci 3G, ponieważ w tym przypadku najlepiej sprawdza się mniejszy rozmiar pakietu.

4397cb2c1327089.png

Teraz przejdź do nowego modułowego interfejsu API i rozpocznij migrację aplikacji.

4. Korzystanie z pakietów zgodności

Pakiety zgodności umożliwiają uaktualnienie pakietu SDK do nowej wersji bez konieczności jednoczesnej zmiany całego kodu Firebase. Możesz je stopniowo uaktualniać do modułu interfejsu API.

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

Pod koniec każdego kroku powinno być możliwe skompilowanie i uruchomienie aplikacji bez awarii. Po migracji rozmiar pakietu powinien się zmniejszyć.

Pobierz nowy pakiet SDK

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

package.json

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

Ponowne instalowanie zależności

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

Zmiana ścieżek importowania

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

  1. Otwórz plik src/firebase.ts
  2. Zastąp istniejące importy 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 skompilować aplikację.
  2. Otwórz kartę przeglądarki z adresem http://localhost:8080 lub odśwież istniejącą.
  3. Wypróbuj aplikację. Wszystko powinno nadal działać.

5. Uaktualnij uwierzytelnianie, aby korzystać z interfejsu Modular API

Usługi Firebase możesz uaktualnić w dowolnej kolejności. W ramach tego ćwiczenia w Codelabs dowiesz się, jak korzystać z uwierzytelniania, ponieważ interfejs Auth API jest stosunkowo prosty. Przejście na nową wersję Firestore wymaga nieco więcej wysiłku i za chwilę dowiesz się, jak to zrobić.

Zaktualizuj zainicjowanie uwierzytelniania

  1. Otwórz plik src/firebase.ts
  2. Dodaj następujący import:

src/firebase.ts

import { initializeAuth, indexedDBLocalPersistence } from 'firebase/auth';
  1. Usuń: import ‘firebase/compat/auth'.
  2. Zamień export const firebaseAuth = app.auth(); na:

src/firebase.ts

export const firebaseAuth = initializeAuth(app, { persistence: [indexedDBLocalPersistence] });
  1. Usuń export type User = firebase.User; z końca pliku. Dane User zostaną wyeksportowane bezpośrednio w aplikacji src/auth.ts, którą zmienisz w następnej kolejności.

Zaktualizuj kod autoryzacji

  1. Otwórz plik src/auth.ts
  2. Na początku pliku dodaj te importy:

src/auth.ts

import { 
    signInAnonymously, 
    signOut,
    onAuthStateChanged,
    User
} from 'firebase/auth';
  1. Usuń User z import { firebaseAuth, User } from './firebase';, bo zaimportowano już User z ‘firebase/auth'.
  2. Zaktualizuj funkcje, aby używały modułowego interfejsu API.

Jak już zauważyliśmy przy aktualizacji instrukcji importowania, pakiety w wersji 9 są zorganizowane wokół funkcji, które można importować. Natomiast w przeciwieństwie do interfejsów API w wersji 8, które działają na podstawie przestrzeni nazw podzielonej na łańcuchy nazw i wzorca usług, pakiety te są porządkowane. To nowa organizacja kodu, która umożliwia potrząsanie nieużywanym kodem przez potrząśnięcie drzew, ponieważ pozwala narzędziom do kompilacji analizować, który kod jest używany, a co nie.

W wersji 9 usługi są przekazywane jako pierwszy argument funkcji. Usługi to obiekty, które otrzymujesz po zainicjowaniu usługi Firebase, np. obiekt zwrócony z funkcji getAuth() lub initializeAuth(). Zawierają one stan określonej usługi Firebase, a funkcja wykorzystuje ten stan do wykonywania jej zadań. Na podstawie tego wzorca implementujemy następujące 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';

Sprawdzanie, czy aplikacja działa

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

Sprawdzanie rozmiaru pakietu

  1. Otwórz Narzędzia deweloperskie w Chrome.
  2. Otwórz kartę Network (Sieć).
  3. Odśwież stronę, aby rejestrować żądania sieciowe.
  4. Znajdź plik main.js i sprawdź jego rozmiar. Twój pakiet został zmniejszony o 100 KB (36 KB w formacie gzip), czyli o około 22% w wyniku zmiany tylko kilku wierszy kodu. Strona wczytuje się też 0,75 s szybciej przy wolnym połączeniu 3G.

2e4eafaf66cd829b.png

6. Uaktualnij aplikację Firebase i Firestore, aby korzystać z modułowego interfejsu API

Zaktualizuj zainicjowanie Firebase

  1. Otwórz plik src/firebase.ts.
  2. Zamień import firebase from ‘firebase/compat/app'; na:

src/firebase.ts

import { initializeApp } from 'firebase/app';
  1. Zamień const app = firebase.initializeApp({...}); na:

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

Zaktualizuj zainicjowanie Firestore

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

src/firebase.ts

import { getFirestore } from 'firebase/firestore';
  1. Zamień export const firestore = app.firestore(); na:

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 FirestoreFieldPath, FirestoreFieldValue i QuerySnapshot. Import z usługi './firebase' powinien teraz wyglądać tak:

src/services.ts

import { firestore } from './firebase';
  1. Na początku pliku zaimportuj funkcje i typy, których będziesz używać:
    **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 znaczniki:

src/services.ts

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

src/services.ts

const tickers = await getDocs(tickersCollRef);

Gotowy kod znajdziesz na stronie search().

Aktualizacja funkcji addToWatchList()

Użyj doc(), aby utworzyć odniesienie do dokumentu do listy obserwowanych notowań użytkownika, a potem dodaj do niego pasek aktywności za pomocą elementu setDoc() z parametrem 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 });
}

Zaktualizuj deleteFromWatchList()

Podobnie usuń pasek aktywności z listy Do obejrzenia, używając funkcji setDoc() i elementu 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 subscriptionToTickerChanges()

  1. Użyj funkcji doc(), aby najpierw utworzyć odniesienie do dokumentu do listy Do obejrzenia użytkownika, a potem odsłuchiwać zmiany na liście do obejrzenia za pomocą funkcji onSnapshot():

src/services.ts

const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
const unsubscribe = onSnapshot(watchlistRef, snapshot => {
   /* subscribe to ticker price changes */
});
  1. Gdy kody znajdują się na liście obserwowanych, użyj funkcji query(), aby utworzyć zapytanie w celu pobrania ich cen, a następnie skorzystaj z narzędzia onSnapshot(), aby wykryć 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);
  });

Całą implementację znajdziesz w sekcji subscribeToTickerChanges().

Aktualizacja funkcji subscriptionToAllTickerChanges()

Najpierw użyjesz usługi collection(), aby utworzyć odwołanie do kolekcji, która zawiera ceny wszystkich kodów, a potem za pomocą onSnapshot() nasłuchujesz 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);
   });
}

Sprawdzanie, czy aplikacja działa

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

Sprawdzanie rozmiaru pakietu

  1. Otwórz Narzędzia deweloperskie w Chrome.
  2. Otwórz kartę Network (Sieć).
  3. Odśwież stronę, aby rejestrować żądania sieciowe.
  4. Poszukaj znaku main.js i sprawdź jego rozmiar. Porównaj go z oryginalnym rozmiarem pakietu – zmniejszyliśmy rozmiar pakietu o ponad 200 KB (63,8 KB w formacie gzip), czyli o 50% mniejszy, co przekłada się na krótszy czas wczytywania o 1,3 s.

7660cdc574ee8571.png

7. Użyj Firestore Lite, aby przyspieszyć początkowe renderowanie stron

Czym jest Firestore Lite?

Pakiet Firestore SDK oferuje złożone funkcje buforowania, strumieniowanie w czasie rzeczywistym, trwałą pamięć masową, synchronizację offline z wieloma kartami, ponawianie prób, optymistyczną równoczesność i wiele innych funkcji, dzięki czemu jest dość duży. Być może jednak chcesz po prostu pobrać te dane raz i nie potrzebujesz żadnych zaawansowanych funkcji. W takich przypadkach stworzyła proste i lekkie rozwiązanie – zupełnie nowy pakiet Firestore Lite.

Świetnym przypadkiem użycia Firestore Lite jest optymalizacja wydajności początkowego renderowania strony, gdzie wystarczy określić, czy użytkownik jest zalogowany, a następnie odczytać niektóre dane z Firetore.

W tym kroku dowiesz się, jak używać Firestore Lite, by zmniejszyć rozmiar pakietu, aby przyspieszyć początkowe renderowanie stron, a potem dynamicznie wczytywać główny pakiet SDK Firestore, aby subskrybować aktualizacje w czasie rzeczywistym.

Zmienisz kod na:

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

Przenoszenie usług czasu rzeczywistego do nowego pliku

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

Musisz jeszcze wprowadzić kilka zmian:

  1. Najpierw utwórz instancję Firestore z głównego pakietu SDK Firestore u góry pliku, która będzie używana w funkcjach. Nie możesz zaimportować instancji Firestore z usługi firebase.ts, ponieważ w kilku krokach zmienisz ją na instancję Firestore Lite, która będzie używana tylko do początkowego renderowania strony.
  2. Następnie pozbądź się zmiennej firstload i chronionego przez nią bloku. 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);
   });
}

Używanie Firestore Lite do pobierania danych

  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, które będą pobierać dane potrzebne do początkowego renderowania przy użyciu 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. Będziesz potrzebować nowo utworzonych funkcji do pobierania danych do początkowego renderowania strony i kilku funkcji pomocniczych do zarządzania stanem aplikacji. 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. Wczytaj plik src/services.realtime za pomocą dynamicznego importu na początku pliku. Zmienna loadRealtimeService to obietnica, która zostanie rozwiązana z usługami czasu rzeczywistego po wczytaniu kodu. Wykorzystasz go 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 onUserChange() na funkcję async, by móc używać await w treści funkcji:

src/main.ts

onUserChange(async user => {
 // callback body
});
  1. Teraz pobierz dane, aby rozpocząć początkowe renderowanie strony za pomocą nowych funkcji, które utworzyliśmy w poprzednim kroku.

W wywołaniu zwrotnym onUserChange() odszukaj warunek „if”, a użytkownik jest zalogowany, a następnie skopiuj znak & wklej kod w 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 innym, w którym żaden użytkownik nie jest zalogowany, za pomocą Firestore lite pobierz informacje o cenach wszystkich akcji, wyrenderuj stronę, a po wczytaniu usług w czasie rzeczywistym obserwuj, jak zmieniają się ceny:

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 sekcji src/main.ts.

Sprawdzanie, czy aplikacja działa

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

Sprawdzanie rozmiaru pakietu

  1. Otwórz Narzędzia deweloperskie w Chrome.
  2. Otwórz kartę Network (Sieć).
  3. Odśwież stronę, aby rejestrować żądania sieciowe
  4. Poszukaj znaku main.js i sprawdź jego rozmiar.
  5. Teraz to tylko 115 KB (34,5 KB w formacie gzip). To o 75% mniejsze niż pierwotny rozmiar pakietu, który wynosił 446 KB(138 KB w formacie gzip). Dzięki temu przy połączeniu 3G strona wczytuje się ponad 2 sekundy szybciej – to znakomita wydajność i lepsze wrażenia użytkownika.

9ea7398a8c8ef81b.png

8. Gratulacje

Gratulacje. Udało Ci się uaktualnić aplikację, dzięki czemu będzie teraz mniejsza i szybsza.

Uaktualniłeś aplikację fragmentami za pomocą pakietów zgodnych. Udało Ci się też użyć Firestore Lite, aby przyspieszyć wstępne renderowanie stron, a następnie dynamicznie ładować główny obiekt Firestore, aby przesyłać strumieniowo zmiany cen.

Podczas tego ćwiczenia z programowania udało Ci się też zmniejszyć rozmiar pakietu i poprawić czas wczytywania:

main.js

rozmiar zasobu (kb)

Rozmiar w pliku gzip (kb)

czas wczytywania (s) (w powolnym 3g)

v8

446

138

4,92

Kompatybilna wersja V9

429

124

4,65

Uwierzytelnianie modułowe tylko w wersji v9

348

102

4,2

w pełni modułowy w wersji v9

244

74,6

3,66

W pełni modułowa wersja 9 + Firestore Lite

117

34,9

2,88

32a71bd5a774e035.png

Znasz już najważniejsze kroki wymagane do uaktualnienia aplikacji internetowej, która korzysta z pakietu SDK Firebase JS w wersji 8, aby mogła korzystać z nowego modułowego pakietu SDK JS.

Więcej informacji

Dokumentacja