1. शुरू करने से पहले
मॉड्यूलर Firebase JS SDK टूल, मौजूदा JS SDK टूल को फिर से लिखा गया वर्शन है. इसे अगले मेजर वर्शन के तौर पर रिलीज़ किया जाएगा. इसकी मदद से, डेवलपर Firebase JS SDK टूल से इस्तेमाल न किए गए कोड को हटा सकते हैं. इससे छोटे बंडल बनाए जा सकते हैं और बेहतर परफ़ॉर्मेंस हासिल की जा सकती है.
मॉड्यूलर JS SDK टूल में सबसे ज़्यादा ध्यान देने वाली बात यह है कि सुविधाओं को अब फ़्री फ़्लोटिंग फ़ंक्शन में व्यवस्थित किया गया है. आपको इन्हें इंपोर्ट करना होगा. इसके बजाय, इन्हें एक ही firebase
नेमस्पेस में रखा गया है, जिसमें सभी सुविधाएं शामिल हैं. कोड को व्यवस्थित करने के इस नए तरीके की मदद से, ट्री शेकिंग की सुविधा मिलती है. साथ ही, आपको यह भी पता चलेगा कि फ़िलहाल v8 Firebase JS SDK टूल का इस्तेमाल करने वाले किसी भी ऐप्लिकेशन को, नए मॉड्यूलर टूल पर कैसे अपग्रेड किया जा सकता है.
अपग्रेड की प्रोसेस को आसान बनाने के लिए, काम करने वाले पैकेज का एक सेट उपलब्ध कराया जाता है. इस कोडलैब में, आपको ऐप्लिकेशन को अलग-अलग हिस्सों में पोर्ट करने के लिए, काम करने वाले पैकेज इस्तेमाल करने का तरीका पता चलेगा.
आपको क्या बनाना है
इस कोडलैब में, आपको v8 JS SDK का इस्तेमाल करने वाले स्टॉक वॉचलिस्ट वेब ऐप्लिकेशन को तीन चरणों में, नए मॉड्यूलर JS SDK पर माइग्रेट करना है:
- काम करने के लिए उपलब्ध पैकेज इस्तेमाल करने के लिए, ऐप्लिकेशन को अपग्रेड करना
- ऐप्लिकेशन को कंपैटबिलिटी पैकेज से मॉड्यूलर एपीआई पर धीरे-धीरे अपग्रेड करना
- ऐप्लिकेशन की परफ़ॉर्मेंस को और बेहतर बनाने के लिए, Firestore Lite का इस्तेमाल करें. यह Firestore SDK टूल का एक हल्का वर्शन है
इस कोडलैब में, Firebase SDK टूल को अपग्रेड करने पर फ़ोकस किया गया है. अन्य कॉन्सेप्ट और कोड ब्लॉक को आसानी से कॉपी और चिपकाया जा सकता है.
आपको इन चीज़ों की ज़रूरत होगी
2. सेट अप करना
कोड पाना
इस प्रोजेक्ट के लिए ज़रूरी सभी चीज़ें, Git repo में मौजूद होती हैं. शुरू करने के लिए, आपको कोड लेना होगा और उसे अपने पसंदीदा डेवलपर एनवायरमेंट में खोलना होगा.
कमांड लाइन से, कोडलैब के GitHub डेटा स्टोर करने की जगह को क्लोन करें:
git clone https://github.com/FirebaseExtended/codelab-modular-sdk.git
इसके अलावा, अगर आपने git इंस्टॉल नहीं किया है, तो रिपॉज़िटरी को ZIP फ़ाइल के तौर पर डाउनलोड करें और डाउनलोड की गई ZIP फ़ाइल को अनपैक करें.
ऐप्लिकेशन इंपोर्ट करना
- अपने IDE का इस्तेमाल करके,
codelab-modular-sdk
डायरेक्ट्री खोलें या इंपोर्ट करें. - ऐप्लिकेशन को स्थानीय तौर पर बनाने और चलाने के लिए ज़रूरी डिपेंडेंसी इंस्टॉल करने के लिए,
npm install
चलाएं. - ऐप्लिकेशन बनाने के लिए,
npm run build
चलाएं. - वेब सर्वर शुरू करने के लिए,
npm run serve
चलाएं - http://localhost:8080 पर जाने के लिए, कोई ब्राउज़र टैब खोलें
3. बेसलाइन तय करना
आपका शुरुआती पॉइंट क्या है?
इस कोडलैब के लिए, स्टॉक वॉचलिस्ट वाला ऐप्लिकेशन तैयार किया गया है. इस कोडलैब में कॉन्सेप्ट को आसानी से समझाने के लिए, कोड को आसान बनाया गया है. साथ ही, इसमें गड़बड़ी को मैनेज करने की सुविधा कम है. अगर आपको प्रोडक्शन ऐप्लिकेशन में इस कोड का फिर से इस्तेमाल करना है, तो पक्का करें कि आपने सभी गड़बड़ियों को ठीक कर लिया हो और सभी कोड की पूरी जांच कर ली हो.
पक्का करें कि ऐप्लिकेशन में सभी चीज़ें काम कर रही हों:
- सबसे ऊपर दाएं कोने में मौजूद, लॉगिन करें बटन का इस्तेमाल करके, बिना पहचान ज़ाहिर किए लॉग इन करें.
- लॉग इन करने के बाद, वॉचलिस्ट में "NFLX", "SBUX", और "T" खोजें और जोड़ें. इसके लिए, जोड़ें बटन पर क्लिक करें, अक्षर टाइप करें, और नीचे पॉप-अप होने वाले खोज के नतीजे की लाइन पर क्लिक करें.
- लाइन के आखिर में मौजूद x पर क्लिक करके, किसी स्टॉक को वॉचलिस्ट से हटाएं.
- स्टॉक की कीमत के रीयल-टाइम अपडेट देखें.
- Chrome DevTools खोलें. इसके बाद, नेटवर्क टैब पर जाएं और कैश मेमोरी बंद करें और अनुरोध की बड़ी लाइनों का इस्तेमाल करें को चुनें. कैश मेमोरी बंद करें से यह पक्का होता है कि रीफ़्रेश करने के बाद, हमें हमेशा नए बदलाव मिलते रहें. साथ ही, अनुरोध की बड़ी लाइनों का इस्तेमाल करें से, किसी संसाधन के लिए ट्रांसफ़र किया गया साइज़ और संसाधन का साइज़, दोनों लाइन में दिखते हैं. इस कोडलैब में, हमारी दिलचस्पी मुख्य रूप से
main.js
के साइज़ में है.
- सिम्युलेटेड थ्रॉटलिंग का इस्तेमाल करके, अलग-अलग नेटवर्क स्थितियों में ऐप्लिकेशन लोड करें. इस कोडलैब में लोड होने में लगने वाले समय को मेज़र करने के लिए, धीमे 3G का इस्तेमाल किया जाएगा. ऐसा इसलिए किया जाएगा, क्योंकि छोटे बंडल साइज़ से सबसे ज़्यादा मदद मिलती है.
अब ऐप्लिकेशन को नए मॉड्यूलर एपीआई पर माइग्रेट करना शुरू करें.
4. डिसप्ले के साथ काम करने से जुड़े पैकेज का इस्तेमाल करना
साथ काम करने वाले पैकेज की मदद से, Firebase के सभी कोड को एक साथ बदले बिना, SDK टूल के नए वर्शन पर अपग्रेड किया जा सकता है. उन्हें धीरे-धीरे मॉड्यूलर API पर अपग्रेड किया जा सकता है.
इस चरण में, आपको Firebase लाइब्रेरी को v8 से नए वर्शन पर अपग्रेड करना होगा. साथ ही, कम्पैटिबिलिटी पैकेज का इस्तेमाल करने के लिए कोड में बदलाव करना होगा. यहां दिए गए चरणों में, आपको मॉड्यूलर एपीआई का इस्तेमाल करने के लिए, सिर्फ़ Firebase Auth कोड को अपग्रेड करने का तरीका पता चलेगा. इसके बाद, Firestore कोड को अपग्रेड करने का तरीका भी पता चलेगा.
हर चरण के आखिर में, आपको ऐप्लिकेशन को बिना किसी रुकावट के कंपाइल और चलाने की सुविधा मिलनी चाहिए. साथ ही, हर प्रॉडक्ट को माइग्रेट करने पर, बंडल के साइज़ में कमी दिखेगी.
नया SDK टूल पाना
package.json
में, डिपेंडेंसी सेक्शन ढूंढें और इसे इनसे बदलें:
package.json
"dependencies": {
"firebase": "^9.0.0"
}
डिपेंडेंसी को फिर से इंस्टॉल करना
हमने डिपेंडेंसी का वर्शन बदल दिया है. इसलिए, डिपेंडेंसी का नया वर्शन पाने के लिए, हमें npm install
को फिर से चलाना होगा.
इंपोर्ट पाथ बदलना
कंपैटिबिलिटी पैकेज, सब-मॉड्यूल firebase/compat
में मौजूद होते हैं. इसलिए, हम इंपोर्ट पाथ को इसी हिसाब से अपडेट करेंगे:
- फ़ाइल
src/firebase.ts
पर जाएं - मौजूदा इंपोर्ट को इन इंपोर्ट से बदलें:
src/firebase.ts
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
पुष्टि करना कि ऐप्लिकेशन काम करता है
- ऐप्लिकेशन को फिर से बनाने के लिए,
npm run build
चलाएं. - ब्राउज़र टैब में http://localhost:8080 खोलें या मौजूदा टैब को रीफ़्रेश करें.
- ऐप्लिकेशन का इस्तेमाल करें. यह पक्का करें कि ऐप्लिकेशन अब भी ठीक से काम कर रहा हो.
5. मॉड्यूलर एपीआई का इस्तेमाल करने के लिए, Auth को अपग्रेड करना
Firebase के प्रॉडक्ट को किसी भी क्रम में अपग्रेड किया जा सकता है. इस कोडलैब में, आपको बुनियादी कॉन्सेप्ट सीखने के लिए, पहले Auth को अपग्रेड करना होगा. ऐसा इसलिए, क्योंकि Auth API का इस्तेमाल करना आसान है. Firestore को अपग्रेड करने की प्रोसेस थोड़ी जटिल है. इसके बारे में अगले लेख में बताया जाएगा.
पुष्टि करने की प्रोसेस को अपडेट करना
- फ़ाइल
src/firebase.ts
पर जाएं - यह इंपोर्ट जोड़ें:
src/firebase.ts
import { initializeAuth, indexedDBLocalPersistence } from 'firebase/auth';
import ‘firebase/compat/auth'.
मिटाएंexport const firebaseAuth = app.auth();
को इनमें से किसी एक से बदलें:
src/firebase.ts
export const firebaseAuth = initializeAuth(app, { persistence: [indexedDBLocalPersistence] });
- फ़ाइल के आखिर में मौजूद
export type User = firebase.User;
हटाएं.User
को सीधेsrc/auth.ts
में एक्सपोर्ट कर दिया जाएगा, जिसे आपको अगले चरण में बदलना है.
पुष्टि करने वाला कोड अपडेट करना
- फ़ाइल
src/auth.ts
पर जाएं - फ़ाइल में सबसे ऊपर, ये इंपोर्ट जोड़ें:
src/auth.ts
import {
signInAnonymously,
signOut,
onAuthStateChanged,
User
} from 'firebase/auth';
import { firebaseAuth, User } from './firebase';
सेUser
को हटाएं, क्योंकि आपने‘firebase/auth'.
सेUser
को पहले ही इंपोर्ट कर लिया है- मॉड्यूलर एपीआई का इस्तेमाल करने के लिए, फ़ंक्शन अपडेट करें.
जैसा कि आपने पहले ही देखा है कि हमने इंपोर्ट स्टेटमेंट को अपडेट किया था. वर्शन 9 में पैकेज, उन फ़ंक्शन के हिसाब से व्यवस्थित किए गए हैं जिन्हें इंपोर्ट किया जा सकता है. वहीं, वर्शन 8 के एपीआई, बिंदु से जुड़े नेमस्पेस और सेवा पैटर्न पर आधारित होते हैं. कोड के इस नए संगठन की मदद से, इस्तेमाल नहीं किए गए कोड को ट्री शेक किया जा सकता है. ऐसा इसलिए किया जा सकता है, क्योंकि इससे बिल्ड टूल को यह पता चलता है कि किस कोड का इस्तेमाल किया गया है और किसका नहीं.
वर्शन 9 में, सेवाओं को फ़ंक्शन के पहले आर्ग्युमेंट के तौर पर पास किया जाता है. सेवाएं वे ऑब्जेक्ट होते हैं जो Firebase सेवा को शुरू करने पर मिलते हैं. जैसे, getAuth()
या initializeAuth()
से मिला ऑब्जेक्ट. ये किसी खास Firebase सेवा की स्थिति को सेव करते हैं. साथ ही, फ़ंक्शन अपने टास्क को पूरा करने के लिए, इस स्थिति का इस्तेमाल करता है. आइए, इन फ़ंक्शन को लागू करने के लिए, इस पैटर्न को लागू करें:
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';
पुष्टि करना कि ऐप्लिकेशन काम कर रहा है
- ऐप्लिकेशन को फिर से बनाने के लिए,
npm run build
चलाएं. - ब्राउज़र टैब में http://localhost:8080 खोलें या मौजूदा टैब को रीफ़्रेश करें
- ऐप्लिकेशन का इस्तेमाल करें. यह पक्का करें कि अब भी सभी चीज़ें काम कर रही हों.
बंडल का साइज़ देखना
- Chrome DevTools खोलें.
- नेटवर्क टैब पर स्विच करें.
- नेटवर्क के अनुरोधों को कैप्चर करने के लिए, पेज को रीफ़्रेश करें.
- main.js ढूंढें और उसका साइज़ देखें. आपने कोड की कुछ लाइनों में बदलाव करके, बंडल का साइज़ 100 केबी (36 केबी जिप किया गया) या करीब 22% कम कर दिया है! साइट, धीमे 3G कनेक्शन पर भी 0.75 सेकंड तेज़ी से लोड हो रही है.
6. मॉड्यूलर एपीआई का इस्तेमाल करने के लिए, Firebase ऐप्लिकेशन और Firestore को अपग्रेड करना
Firebase को शुरू करने की प्रोसेस को अपडेट करना
- फ़ाइल
src/firebase.ts.
पर जाएं import firebase from ‘firebase/compat/app';
को इनमें से किसी एक से बदलें:
src/firebase.ts
import { initializeApp } from 'firebase/app';
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"
});
Firestore को शुरू करने की प्रोसेस अपडेट करना
- उसी फ़ाइल में
src/firebase.ts,
कोimport 'firebase/compat/firestore';
से बदलें
src/firebase.ts
import { getFirestore } from 'firebase/firestore';
export const firestore = app.firestore();
को इनमें से किसी एक से बदलें:
src/firebase.ts
export const firestore = getFirestore();
- "
export const firestore = ...
" के बाद की सभी लाइनें हटाएं
इंपोर्ट अपडेट करना
src/services.ts.
फ़ाइल खोलें- इंपोर्ट से
FirestoreFieldPath
,FirestoreFieldValue
, औरQuerySnapshot
को हटाएं.'./firebase'
से इंपोर्ट किया गया डेटा अब कुछ ऐसा दिखेगा:
src/services.ts
import { firestore } from './firebase';
- फ़ाइल में सबसे ऊपर, वे फ़ंक्शन और टाइप इंपोर्ट करें जिनका आपको इस्तेमाल करना है:
**src/services.ts**
import {
collection,
getDocs,
doc,
setDoc,
arrayUnion,
arrayRemove,
onSnapshot,
query,
where,
documentId,
QuerySnapshot
} from 'firebase/firestore';
search() को अपडेट करना
- सभी टिकर वाले कलेक्शन का रेफ़रंस बनाएं:
src/services.ts
const tickersCollRef = collection(firestore, 'current');
- कलेक्शन से सभी दस्तावेज़ फ़ेच करने के लिए,
getDocs()
का इस्तेमाल करें:
src/services.ts
const tickers = await getDocs(tickersCollRef);
पूरा कोड देखने के लिए, search()
देखें.
Update addToWatchList()
उपयोगकर्ता की वॉचलिस्ट में दस्तावेज़ का रेफ़रंस बनाने के लिए, doc()
का इस्तेमाल करें. इसके बाद, arrayUnion()
के साथ setDoc()
का इस्तेमाल करके, उसमें टिकर जोड़ें:
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 });
}
deleteFromWatchList() को अपडेट करना
इसी तरह, arrayRemove()
के साथ setDoc()
का इस्तेमाल करके, उपयोगकर्ता की वॉचलिस्ट से टिकर हटाएं:
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 });
}
subscribeToTickerChanges() को अपडेट करना
- सबसे पहले, उपयोगकर्ता की वॉचलिस्ट का दस्तावेज़ रेफ़रंस बनाने के लिए
doc()
का इस्तेमाल करें. इसके बाद,onSnapshot()
का इस्तेमाल करके वॉचलिस्ट में हुए बदलावों को सुनें:
src/services.ts
const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
const unsubscribe = onSnapshot(watchlistRef, snapshot => {
/* subscribe to ticker price changes */
});
- वॉचलिस्ट में टिकर जोड़ने के बाद, उनकी कीमतें फ़ेच करने के लिए
query()
का इस्तेमाल करके क्वेरी बनाएं. साथ ही, उनकी कीमत में हुए बदलावों को सुनने के लिएonSnapshot()
का इस्तेमाल करें:
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);
});
पूरी तरह से लागू करने के लिए, subscribeToTickerChanges() देखें.
subscribeToAllTickerChanges() को अपडेट करना
सबसे पहले, आपको collection()
का इस्तेमाल करके उस कलेक्शन का रेफ़रंस बनाना होगा जिसमें सभी टिकर की कीमतें शामिल हैं. इसके बाद, कीमत में हुए बदलावों को सुनने के लिए onSnapshot()
का इस्तेमाल करें:
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);
});
}
पुष्टि करना कि ऐप्लिकेशन काम कर रहा है
- ऐप्लिकेशन को फिर से बनाने के लिए,
npm run build
चलाएं. - ब्राउज़र टैब में http://localhost:8080 खोलें या मौजूदा टैब को रीफ़्रेश करें
- ऐप्लिकेशन का इस्तेमाल करें. यह पक्का करें कि अब भी सभी चीज़ें काम कर रही हों.
बंडल का साइज़ देखना
- Chrome DevTools खोलें.
- नेटवर्क टैब पर स्विच करें.
- नेटवर्क के अनुरोधों को कैप्चर करने के लिए, पेज को रीफ़्रेश करें.
main.js
ढूंढें और उसका साइज़ देखें. इसकी तुलना फिर से ओरिजनल बंडल साइज़ से करें - हमने बंडल साइज़ को 200 केबी (63.8 केबी जिप किया गया) या 50% तक कम कर दिया है. इसका मतलब है कि बंडल 1.3 सेकंड पहले लोड होगा!
7. पेज के शुरुआती रेंडरिंग की स्पीड बढ़ाने के लिए, Firestore Lite का इस्तेमाल करना
Firestore Lite क्या है?
Firestore SDK टूल, कैश मेमोरी का बेहतर तरीके से इस्तेमाल करने, रीयल-टाइम स्ट्रीमिंग, डेटा को लगातार स्टोर करने, एक से ज़्यादा टैब को ऑफ़लाइन सिंक करने, फिर से कोशिश करने, ऑप्टिमिज़्म से जुड़ी कई सुविधाएं, और बहुत कुछ उपलब्ध कराता है. इसलिए, यह टूल काफ़ी बड़ा है. हालांकि, हो सकता है कि आपको किसी बेहतर सुविधा के बिना, सिर्फ़ एक बार डेटा चाहिए हो. ऐसे मामलों के लिए, Firestore ने एक आसान और हल्का समाधान बनाया है. यह एक नया पैकेज है — Firestore Lite.
Firestore Lite का इस्तेमाल करने का एक बेहतरीन उदाहरण, शुरुआती पेज को रेंडर करने की परफ़ॉर्मेंस को ऑप्टिमाइज़ करना है. इसमें आपको सिर्फ़ यह जानना होता है कि उपयोगकर्ता लॉग इन है या नहीं. इसके बाद, Firestore से कुछ डेटा पढ़कर उसे दिखाया जाता है.
इस चरण में, आपको शुरुआती पेज को तेज़ी से रेंडर करने के लिए, बंडल के साइज़ को कम करने के लिए Firestore Lite का इस्तेमाल करने का तरीका पता चलेगा. इसके बाद, रीयल-टाइम अपडेट की सदस्यता लेने के लिए, मुख्य Firestore SDK टूल को डाइनैमिक तरीके से लोड करने का तरीका पता चलेगा.
आपको कोड को फिर से बनाने के लिए:
- रीयल-टाइम सेवाओं को किसी अलग फ़ाइल में ले जाएं, ताकि उन्हें डाइनैमिक इंपोर्ट का इस्तेमाल करके डाइनैमिक तौर पर लोड किया जा सके.
- वॉचलिस्ट और स्टॉक की कीमतें पाने के लिए, Firestore Lite का इस्तेमाल करने के लिए नए फ़ंक्शन बनाएं.
- शुरुआती पेज को रेंडर करने के लिए डेटा पाने के लिए, Firestore Lite के नए फ़ंक्शन का इस्तेमाल करें. इसके बाद, रीयल-टाइम अपडेट सुनने के लिए रीयल-टाइम सेवाओं को डाइनैमिक तौर पर लोड करें.
रीयल-टाइम सेवाओं को नई फ़ाइल में ले जाना
src/services.realtime.ts.
नाम की नई फ़ाइल बनाएं- फ़ंक्शन
subscribeToTickerChanges()
औरsubscribeToAllTickerChanges()
कोsrc/services.ts
से नई फ़ाइल में ले जाएं. - नई फ़ाइल में सबसे ऊपर ज़रूरी इंपोर्ट जोड़ें.
आपको यहां कुछ और बदलाव करने होंगे:
- सबसे पहले, फ़ंक्शन में इस्तेमाल करने के लिए, फ़ाइल में सबसे ऊपर मौजूद मुख्य Firestore SDK टूल से Firestore इंस्टेंस बनाएं. यहां
firebase.ts
से Firestore इंस्टेंस इंपोर्ट नहीं किया जा सकता, क्योंकि आपको इसे कुछ चरणों में Firestore Lite इंस्टेंस में बदलना है. इसका इस्तेमाल सिर्फ़ शुरुआती पेज को रेंडर करने के लिए किया जाएगा. - दूसरा,
firstload
वैरिएबल और उसके बाद वाले if ब्लॉक को हटाएं. इनकी सुविधाओं को नए फ़ंक्शन में ट्रांसफ़र कर दिया जाएगा. ये फ़ंक्शन, अगले चरण में बनाए जाएंगे.
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);
});
}
डेटा फ़ेच करने के लिए, Firestore lite का इस्तेमाल करना
src/services.ts.
खोलें- इंपोर्ट पाथ को
‘firebase/firestore'
से‘firebase/firestore/lite',
में बदलें,getDoc
जोड़ें, और इंपोर्ट सूची सेonSnapshot
हटाएं:
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';
- 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);
}
src/firebase.ts
खोलें और इंपोर्ट पाथ को‘firebase/firestore'
से‘firebase/firestore/lite':
में बदलें
src/firebase.ts
import { getFirestore } from 'firebase/firestore/lite';
सभी को एक साथ जोड़ना
src/main.ts.
खोलें- शुरुआती पेज को रेंडर करने के लिए डेटा फ़ेच करने के लिए, आपको नए फ़ंक्शन बनाने होंगे. साथ ही, ऐप्लिकेशन की स्थिति को मैनेज करने के लिए, कुछ हेल्पर फ़ंक्शन बनाने होंगे. इसलिए, अब इंपोर्ट अपडेट करें:
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';
- फ़ाइल में सबसे ऊपर, डाइनैमिक इंपोर्ट का इस्तेमाल करके
src/services.realtime
लोड करें. वैरिएबलloadRealtimeService
एक प्रॉमिस है, जो कोड लोड होने के बाद रीयल-टाइम सेवाओं के साथ रिज़ॉल्व हो जाएगा. इसका इस्तेमाल, रीयल-टाइम अपडेट की सदस्यता लेने के लिए किया जाएगा.
src/main.ts
const loadRealtimeService = import('./services.realtime');
loadRealtimeService.then(() => {
setRealtimeServicesLoaded(true);
});
onUserChange()
के कॉलबैक कोasync
फ़ंक्शन में बदलें, ताकि हम फ़ंक्शन के मुख्य हिस्से मेंawait
का इस्तेमाल कर सकें:
src/main.ts
onUserChange(async user => {
// callback body
});
- अब पिछले चरण में बनाए गए नए फ़ंक्शन का इस्तेमाल करके, शुरुआती पेज को रेंडर करने के लिए डेटा फ़ेच करें.
onUserChange()
कॉलबैक में, वह if स्टेटमेंट ढूंढें जिसमें उपयोगकर्ता लॉग इन है. इसके बाद, 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
}
}
- else ब्लॉक में, जहां कोई उपयोगकर्ता लॉग इन नहीं है, वहां firestore lite का इस्तेमाल करके सभी स्टॉक की कीमत की जानकारी फ़ेच करें. इसके बाद, पेज को रेंडर करें और रीयल-टाइम सेवाएं लोड होने के बाद, कीमत में हुए बदलावों को सुनें:
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 })
});
});
}
पूरा कोड देखने के लिए, src/main.ts देखें.
पुष्टि करना कि ऐप्लिकेशन काम कर रहा है
- ऐप्लिकेशन को फिर से बनाने के लिए,
npm run build
चलाएं. - ब्राउज़र टैब में http://localhost:8080 खोलें या मौजूदा टैब को रीफ़्रेश करें.
बंडल का साइज़ देखना
- Chrome DevTools खोलें.
- नेटवर्क टैब पर स्विच करें.
- नेटवर्क के अनुरोधों को कैप्चर करने के लिए, पेज को रीफ़्रेश करें
main.js
ढूंढें और उसका साइज़ देखें.- अब यह सिर्फ़ 115 केबी (34.5 केबी जिप किया गया) है. यह मूल बंडल साइज़ से 75% छोटा है, जो 446 केबी(138 केबी जिप किया गया) था! इस वजह से, साइट 3G कनेक्शन पर दो सेकंड से ज़्यादा तेज़ी से लोड हो रही है. इससे, साइट की परफ़ॉर्मेंस और उपयोगकर्ता अनुभव बेहतर हुआ है!
8. बधाई
बधाई हो, आपने ऐप्लिकेशन को अपग्रेड कर लिया है. साथ ही, इसे छोटा और तेज़ बनाया है!
आपने ऐप्लिकेशन को धीरे-धीरे अपग्रेड करने के लिए, काम करने वाले पैकेज का इस्तेमाल किया. साथ ही, शुरुआती पेज की रेंडरिंग को तेज़ करने के लिए, Firestore Lite का इस्तेमाल किया. इसके बाद, कीमत में हुए बदलावों को स्ट्रीम करने के लिए, मुख्य Firestore को डाइनैमिक तौर पर लोड किया.
इस कोडलैब के दौरान, आपने बंडल का साइज़ भी कम किया और उसके लोड होने में लगने वाले समय को भी बेहतर बनाया:
main.js | रिसॉर्स का साइज़ (केबी) | Gzip किया गया साइज़ (केबी) | लोड होने में लगने वाला समय (सेकंड) (धीमे 3G पर) |
v8 | 446 | 138 | 4.92 |
v9 के साथ काम करने वाला | 429 | 124 | 4.65 |
सिर्फ़ v9 के लिए मॉड्यूलर Auth | 348 | 102 | 4.2 |
v9 पूरी तरह से मॉड्यूलर | 244 | 74.6 | 3.66 |
v9 पूरी तरह से मॉड्यूलर + Firestore lite | 117 | 34.9 | 2.88 |
अब आपको वेब ऐप्लिकेशन को अपग्रेड करने के मुख्य चरणों के बारे में पता है. यह ऐप्लिकेशन, नए मॉड्यूलर JS SDK टूल का इस्तेमाल करने के लिए, v8 Firebase JS SDK टूल का इस्तेमाल करता है.