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

Zwiększ wydajność swojej aplikacji internetowej, migrując na modułowy pakiet SDK Firebase JS

Informacje o tym ćwiczeniu (w Codelabs)

subjectOstatnia aktualizacja: lis 1, 2024
account_circleAutorzy: Feiyang Chen

1. Zanim zaczniesz

Modułowy pakiet SDK Firebase JS to nowa wersja dotychczasowego pakietu SDK JS, która zostanie wydana jako kolejna wersja główna. Umożliwia to 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 JS jest to, że funkcje są teraz zorganizowane w funkcje swobodne, które będziesz importować, a nie w jednym zakresie nazw firebase, który obejmuje wszystko. Ten nowy sposób organizacji kodu umożliwia usuwanie niepotrzebnych elementów z drzewa. Dowiesz się też, jak uaktualnić dowolną aplikację, która obecnie korzysta z wersji 8 pakietu Firebase JS SDK, 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 etapami.

Co utworzysz

W tym laboratorium programistycznym przeprowadzisz w 3 etapach migrację istniejącej internetowej aplikacji do śledzenia akcji, która korzysta z pakietu SDK JS v8, na nowy modułowy pakiet SDK JS:

  • Zaktualizuj aplikację, aby używać pakietów zgodności.
  • stopniowo przekształcać aplikację z pakietów zgodności na interfejs API w wersji modułowej.
  • Użyj Firestore Lite, czyli lekkiej implementacji pakietu SDK Firestore, aby jeszcze bardziej zwiększyć wydajność aplikacji.

2d351cb47b604ad7.png

Ten warsztat dotyczy uaktualniania pakietu SDK Firebase. Inne koncepcje i bloki kodu zostały zamaskowane. Można je po prostu skopiować i wkleić.

Czego potrzebujesz

  • przeglądarkę, np. Chrome;
  • Wybrany edytor kodu lub tekstowy, np. WebStorm, Atom, Sublime lub VS Code.
  • Menedżer pakietów npm, który jest zwykle dostarczany z Node.js.
  • przykładowy kod z codelab (jak go pobrać, dowiesz się z następnego kroku w codelab);

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.

Sklonuj repozytorium GitHub z codelab z poziomu wiersza poleceń:

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

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

Importowanie aplikacji

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

71a8a7d47392e8f4.png

3. Ustal wartość odniesienia

Jaki jest Twój punkt wyjścia?

Punktem wyjścia jest aplikacja z listą obserwowanych akcji zaprojektowana na potrzeby tego ćwiczenia. Kod został uproszczony, aby zilustrować pojęcia w tym ćwiczeniu, i nie zawiera wielu elementó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 przejrzeć cały kod.

Sprawdź, czy wszystko działa w aplikacji:

  1. Zaloguj się anonimowo, klikając przycisk logowania w prawym górnym rogu.
  2. Po zalogowaniu się wyszukaj i dodaj „NFLX”, „SBUX” i „T” do listy obserwowanych, klikając przycisk Dodaj, wpisując litery i klikając wiersz wyników wyszukiwania, który pojawi się poniżej.
  3. Aby usunąć akcje z listy obserwowanych, kliknij x na końcu wiersza.
  4. Obserwuj bieżące zmiany ceny akcji.
  5. Otwórz Narzędzia deweloperskie w Chrome, otwórz kartę Sieć i odznacz opcje Wyłącz pamięć podręczną oraz Używaj dużych wierszy żądań. Opcja Wyłącz pamięć podręczną sprawia, że po odświeżeniu zawsze otrzymujemy najnowsze zmiany, a opcja Użyj dużych wierszy żądań sprawia, że wiersz wyświetla zarówno rozmiar przesłanych danych, jak i rozmiar zasobu. W tym Codelab interesuje nas głównie rozmiar main.js.

48a096debb2aa940.png

  1. Załaduj aplikację w różnych warunkach sieciowych, symulując ograniczanie. W tym ćwiczeniu będziesz używać wolnego 3G do pomiaru czasu wczytywania, ponieważ w takich warunkach mniejszy rozmiar pakietu jest najbardziej przydatny.

4397cb2c1327089.png

Teraz zacznij migrować aplikację 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 przenosić je na modułowe API.

W tym kroku uaktualnisz bibliotekę Firebase z wersji 8 na nową i zmienisz kod, aby używać pakietów zgodności. Z tych kroków dowiesz się, jak najpierw uaktualnić tylko kod uwierzytelniania Firebase, aby używać modułowego interfejsu API, a potem uaktualnić kod Firestore.

Po zakończeniu każdego kroku powinnaś/powinieneś mieć możliwość skompilowania i uruchomienia aplikacji bez błędów. W miarę migracji poszczególnych usług powinieneś/powinnaś też zauważyć zmniejszenie rozmiaru pakietu.

Pobierz nowy pakiet SDK

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

package.json

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

Ponowne instalowanie zależności

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

Zmiana ścieżek importu

Pakiety zgodności są dostępne w ramach podmodułu firebase/compat, więc zaktualizujemy ścieżki importu:

  1. Otwórz plik src/firebase.ts
  2. Zastąp dotychczasowe importy tymi:

src/firebase.ts

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

Sprawdzanie, czy aplikacja działa prawidłowo

  1. Uruchom npm run build, aby ponownie utworzyć aplikację.
  2. Otwórz kartę przeglądarki http://localhost:8080 lub odśwież obecną kartę.
  3. Pobaw się aplikacją. Wszystko powinno działać.

5. Uaktualnianie Auth do wersji korzystającej z modułowego interfejsu API

Usługi Firebase możesz przekształcać w dowolnej kolejności. W tym ćwiczeniu najpierw uaktualnisz interfejs Auth, aby poznać podstawowe pojęcia, ponieważ interfejs Auth API jest stosunkowo prosty. Uaktualnianie Firestore jest nieco bardziej skomplikowane, ale w następnym kroku dowiesz się, jak to zrobić.

Inicjowanie uwierzytelniania aktualizacji

  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();:

src/firebase.ts

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

Zaktualizuj kod autoryzacji

  1. Otwórz plik src/auth.ts
  2. Dodaj do góry pliku te instrukcje importu:

src/auth.ts

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

Jak już widzisz, gdy aktualizowaliśmy instrukcję importowania, pakiety w wersji 9 są zorganizowane wokół funkcji, które możesz importować, w przeciwieństwie do interfejsów API w wersji 8, które są oparte na łańcuchu nazw domeny i wzorze usługi. To nowe uporządkowanie kodu umożliwia usuwanie nieużywanego kodu z drzewa, 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, które otrzymujesz po zainicjowaniu usługi Firebase, np. obiekt zwrócony przez funkcję getAuth() lub initializeAuth(). Zawierają one stan konkretnej usługi Firebase, a funkcja korzysta z tego stanu do wykonywania swoich zadań. Zastosujmy ten wzór do implementacji tych funkcji:

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 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ż obecną kartę.
  3. Pobaw się aplikacją. Wszystko powinno 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. Odszukaj plik main.js i sprawdź jego rozmiar. Rozmiar pakietu zmniejszył się o 100 KB (36 KB w formacie skompresowanym) lub o około 22%, ponieważ zmieniono tylko kilka linii kodu. Strona wczytuje się też o 0,75 s szybciej przy wolniejszym połączeniu 3G.

2e4eafaf66cd829b.png

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

Aktualizowanie inicjalizacji Firebase

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

src/firebase.ts

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

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 inicjalizacji 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();:

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 wartości FirestoreFieldPath, FirestoreFieldValueQuerySnapshot. Import z './firebase' powinien wyglądać tak:

src/services.ts

import { firestore } from './firebase';
  1. U góry 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 zawierającej wszystkie tickery:

src/services.ts

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

src/services.ts

const tickers = await getDocs(tickersCollRef);

Pełny kod znajdziesz na stronie search().

Zaktualizuj funkcję addToWatchList()

Użyj elementu doc(), aby utworzyć odwołanie do dokumentu na liście obserwowanych, a następnie dodaj do niego ticker za pomocą elementu setDoc() z elementem 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 możesz usunąć ticker z listy Do obejrzenia użytkownika, używając setDoc() z 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 });
}

Zaktualizuj subscribeToTickerChanges()

  1. Najpierw użyj doc(), aby utworzyć odwołanie do dokumentu na liście obserwowanych, a potem odsłuchaj zmiany na liście 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 masz już tickery na liście obserwowanych, użyj zapytania query(), aby pobrać ich ceny, i zapytania onSnapshot(), aby śledzić zmiany ich 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 funkcji subscribeToTickerChanges().

Zaktualizuj subscribeToAllTickerChanges()

Najpierw użyjesz funkcji collection(), aby utworzyć odwołanie do kolekcji zawierającej ceny wszystkich tickerów, a potem użyjesz funkcji onSnapshot(), aby słuchać 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 utworzyć aplikację.
  2. Otwórz kartę przeglądarki z adresem http://localhost:8080 lub odśwież obecną kartę.
  3. Pobaw się aplikacją. Wszystko powinno 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 main.js i sprawdź jego rozmiar. Porównaj to z pierwotnym rozmiarem pakietu – zmniejszyliśmy go o ponad 200 KB (63,8 KB w formacie skompresowanym) lub o 50%, co przekłada się na skrócenie czasu wczytywania o 1,3 s.

7660cdc574ee8571.png

7. Używanie Firestore Lite do przyspieszania 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 na wielu kartach, próby ponownego połączenia, optymistyczną współbieżność i wiele innych funkcji, dlatego jego rozmiar jest dość duży. Możesz jednak po prostu chcieć pobrać dane tylko raz, bez korzystania z funkcji zaawansowanych. W takich przypadkach Firestore oferuje proste i lekkie rozwiązanie, czyli zupełnie nowy pakiet – Firestore Lite.

Jednym z przydatnych zastosowań Firestore Lite jest optymalizacja wydajności początkowego renderowania strony, w której przypadku wystarczy wiedzieć, czy użytkownik jest zalogowany, a potem odczytać dane z Firestore, aby je wyświetlić.

W tym kroku dowiesz się, jak użyć Firestore lite, aby zmniejszyć rozmiar pakietu i przyspieszyć początkowe renderowanie strony, a potem wczytać główny pakiet SDK Firestore dynamicznie, aby subskrybować aktualizacje w czasie rzeczywistym.

Przepisz kod, aby:

  1. Przenoszenie usług w czasie rzeczywistym do osobnego pliku, aby można je było wczytywać dynamicznie za pomocą importu dynamicznego.
  2. Utwórz nowe funkcje, aby używać Firestore Lite do pobierania cen akcji i list obserwowanych.
  3. Użyj nowych funkcji Firestore Lite, aby pobrać dane potrzebne do początkowego renderowania strony, a potem dynamicznie wczytaj usługi w czasie rzeczywistym, aby odbierać aktualizacje w czasie rzeczywistym.

Przenoszenie usług 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 importy 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, aby można było jej używać w funkcjach. Nie możesz tu zaimportować instancji Firestore z 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. Po drugie, pozbądź się zmiennej firstload i zabezpieczonego przez nią bloku if. 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 z 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 służące do pobierania danych potrzebnych do początkowego 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 plik 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 początkowego renderowania strony, a kilka funkcji pomocniczych do zarządzania stanem aplikacji. Zaktualizuj teraz 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 rozwiązana przez usługi w czasie rzeczywistym po załadowaniu kodu. Użyjesz go później, aby subskrybować aktualizacje w czasie rzeczywistym.

src/main.ts

const loadRealtimeService = import('./services.realtime');
loadRealtimeService
.then(() => {
   setRealtimeServicesLoaded
(true);
});
  1. Zmień funkcję onUserChange() na funkcję async, aby móc używać w jej treści funkcji await:

src/main.ts

onUserChange(async user => {
 
// callback body
});
  1. Teraz pobierz dane, aby dokonać początkowego renderowania strony za pomocą nowych funkcji utworzonych w poprzednim kroku.

W funkcji zwracającej onUserChange() odszukaj warunek if, w którym użytkownik jest zalogowany, a potem skopiuj i wklej kod w oświadczeniu 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 produktów za pomocą Firestore Lite, wyrenderuj stronę, a potem 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.

Sprawdzanie, czy aplikacja działa

  1. Uruchom npm run build, aby ponownie utworzyć aplikację.
  2. Otwórz kartę przeglądarki http://localhost:8080 lub odśwież obecną 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 main.js i sprawdź jego rozmiar.
  5. Teraz ma on tylko 115 KB (34,5 KB po skompresowaniu). To o 75% mniej niż rozmiar oryginalnego pakietu, który wynosił 446 KB(138 KB po skompresowaniu). W efekcie witryna wczytuje się o ponad 2 sekundy szybciej w przypadku połączenia 3G – to świetna wydajność i wygoda dla użytkowników.

9ea7398a8c8ef81b.png

8. Gratulacje

Gratulacje! Udało Ci się uaktualnić aplikację, zmniejszyć jej rozmiar i przyspieszyć jej działanie.

Używasz pakietów zgodności do stopniowego ulepszania aplikacji i Firestore Lite do przyspieszania początkowego renderowania strony, a potem wczytujesz dynamicznie główną bazę danych Firestore, aby przesyłać zmiany cen.

W ramach tego ćwiczenia udało Ci się też zmniejszyć rozmiar pakietu i skrócić czas jego wczytywania:

main.js

rozmiar zasobu (KB)

rozmiar skompresowany (KB)

Czas wczytywania (s) (połączenie 3G o niskiej szybkości)

v8

446

138

4,92

v9 zgodny

429

124

4,65

tylko w Auth modułowym w wersji 9

348

102

4.2

v9 w pełni modułowej

244

74,6

3,66

v9 w wersji całkowicie modułowej + Firestore lite

117

34,9

2,88

32a71bd5a774e035.png

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

Więcej informacji

Dokumenty referencyjne