1. ก่อนเริ่มต้น
Firebase JS SDK แบบแยกส่วนคือการเขียน JS SDK ที่มีอยู่ใหม่ และจะเปิดตัวเป็นเวอร์ชันหลักรุ่นถัดไป ซึ่งช่วยให้นักพัฒนาแอปยกเว้นโค้ดที่ไม่ได้ใช้จาก Firebase JS SDK เพื่อสร้างชุดข้อมูลขนาดเล็กลงและมีประสิทธิภาพดียิ่งขึ้น
ความแตกต่างที่เห็นได้ชัดที่สุดใน JS SDK แบบแยกส่วนคือตอนนี้ฟีเจอร์ต่างๆ จะจัดระเบียบอยู่ในฟังก์ชันแบบลอยตัวอิสระที่คุณจะนำเข้า ซึ่งแตกต่างจากในfirebaseเนมสเปซเดียวที่มีทุกอย่าง การจัดระเบียบโค้ดแบบใหม่นี้ช่วยให้สามารถทำการกำจัดโค้ดที่ไม่จำเป็นได้ และคุณจะได้เรียนรู้วิธีอัปเกรดแอปที่ใช้ Firebase JS SDK v8 อยู่ในปัจจุบันเป็นแบบโมดูลาร์ใหม่
เรามีชุดแพ็กเกจความเข้ากันได้เพื่อให้กระบวนการอัปเกรดเป็นไปอย่างราบรื่น ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีใช้แพ็กเกจความเข้ากันได้เพื่อพอร์ตแอปทีละส่วน
สิ่งที่คุณจะสร้าง
ใน Codelab นี้ คุณจะค่อยๆ ย้ายข้อมูลเว็บแอปรายการเฝ้าดูหุ้นที่มีอยู่ซึ่งใช้ v8 JS SDK ไปยัง JS SDK แบบโมดูลใหม่ใน 3 ขั้นตอน
- อัปเกรดแอปเพื่อใช้แพ็กเกจความเข้ากันได้
- อัปเกรดแอปจากแพ็กเกจความเข้ากันได้เป็น API แบบแยกส่วนทีละส่วน
- ใช้ Firestore Lite ซึ่งเป็นการติดตั้งใช้งาน SDK ของ Firestore แบบเบาเพื่อปรับปรุงประสิทธิภาพของแอปให้ดียิ่งขึ้น

Codelab นี้มุ่งเน้นที่การอัปเกรด Firebase SDK แนวคิดและบล็อกโค้ดอื่นๆ จะได้รับการอธิบายอย่างย่อและจัดไว้ให้คุณคัดลอกและวางได้ง่ายๆ
สิ่งที่คุณต้องมี
2. ตั้งค่า
รับรหัส
ทุกสิ่งที่คุณต้องการสำหรับโปรเจ็กต์นี้อยู่ในที่เก็บ Git หากต้องการเริ่มต้นใช้งาน คุณจะต้องคัดลอกโค้ดและเปิดในสภาพแวดล้อมการพัฒนาที่คุณชื่นชอบ
โคลนที่เก็บ Github ของ Codelab จากบรรทัดคำสั่งโดยใช้คำสั่งต่อไปนี้
git clone https://github.com/FirebaseExtended/codelab-modular-sdk.git
หรือหากไม่ได้ติดตั้ง git คุณสามารถดาวน์โหลดที่เก็บเป็นไฟล์ ZIP และแตกไฟล์ ZIP ที่ดาวน์โหลดมา
นำเข้าแอป
- เปิดหรือนำเข้าไดเรกทอรี
codelab-modular-sdkโดยใช้ IDE - เรียกใช้
npm installเพื่อติดตั้งการอ้างอิงที่จำเป็นในการสร้างและเรียกใช้แอปในเครื่อง - เรียกใช้
npm run buildเพื่อสร้างแอป - เรียกใช้
npm run serveเพื่อเริ่มเว็บเซิร์ฟเวอร์ - เปิดแท็บเบราว์เซอร์ไปที่ http://localhost:8080

3. กำหนดพื้นฐาน
จุดเริ่มต้นของคุณคืออะไร
จุดเริ่มต้นของคุณคือแอปรายการเฝ้าดูหุ้นที่ออกแบบมาสำหรับ Codelab นี้ เราได้ลดความซับซ้อนของโค้ดเพื่อแสดงแนวคิดในโค้ดแล็บนี้ และโค้ดนี้มีการจัดการข้อผิดพลาดเพียงเล็กน้อย หากเลือกที่จะนำโค้ดนี้ไปใช้ซ้ำในแอปเวอร์ชันที่ใช้งานจริง โปรดตรวจสอบว่าคุณได้จัดการข้อผิดพลาดและทดสอบโค้ดทั้งหมดอย่างละเอียดแล้ว
ตรวจสอบว่าทุกอย่างในแอปทำงานได้
- เข้าสู่ระบบโดยไม่ระบุตัวตนโดยใช้ปุ่มเข้าสู่ระบบที่มุมขวาบน
- หลังจากเข้าสู่ระบบแล้ว ให้ค้นหาและเพิ่ม "NFLX", "SBUX" และ "T" ลงในรายการเฝ้าดูโดยคลิกปุ่มเพิ่ม พิมพ์ตัวอักษร และคลิกแถวผลการค้นหาที่ปรากฏขึ้นด้านล่าง
- นำหุ้นออกจากรายการที่สนใจโดยคลิก x ที่ท้ายแถว
- ดูข้อมูลอัปเดตราคาหุ้นแบบเรียลไทม์
- เปิดเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome ไปที่แท็บเครือข่าย แล้วเลือกปิดใช้แคชและใช้แถวคำขอขนาดใหญ่ ปิดใช้แคชช่วยให้เราได้รับการเปลี่ยนแปลงล่าสุดเสมอหลังจากรีเฟรช และใช้แถวคำขอขนาดใหญ่ทำให้แถวแสดงทั้งขนาดที่ส่งและขนาดทรัพยากรสำหรับทรัพยากร ใน Codelab นี้ เราจะสนใจขนาดของ
main.jsเป็นหลัก

- โหลดแอปภายใต้สภาวะเครือข่ายต่างๆ โดยใช้การควบคุมจำลอง คุณจะใช้ 3G แบบช้าเพื่อวัดเวลาในการโหลดในโค้ดแล็บนี้ เนื่องจากเป็นที่ที่ขนาด Bundle ที่เล็กลงจะช่วยได้มากที่สุด

ตอนนี้คุณสามารถเริ่มย้ายข้อมูลแอปไปยัง Modular API ใหม่ได้แล้ว
4. ใช้แพ็กเกจความเข้ากันได้
แพ็กเกจความเข้ากันได้ช่วยให้คุณอัปเกรดเป็น SDK เวอร์ชันใหม่ได้โดยไม่ต้องเปลี่ยนโค้ด Firebase ทั้งหมดในครั้งเดียว คุณสามารถอัปเกรดเป็น Modular API ได้ทีละน้อย
ในขั้นตอนนี้ คุณจะอัปเกรดไลบรารี Firebase จาก v8 เป็นเวอร์ชันใหม่ และเปลี่ยนโค้ดให้ใช้แพ็กเกจความเข้ากันได้ ในขั้นตอนต่อไปนี้ คุณจะได้เรียนรู้วิธีอัปเกรดเฉพาะโค้ด Firebase Auth เพื่อใช้ Modular API ก่อน แล้วจึงอัปเกรดโค้ด Firestore
เมื่อสิ้นสุดแต่ละขั้นตอน คุณควรจะคอมไพล์และเรียกใช้แอปได้โดยไม่มีข้อผิดพลาด และเห็นว่าขนาดของ Bundle ลดลงเมื่อเราย้ายข้อมูลแต่ละผลิตภัณฑ์
รับ SDK ใหม่
ค้นหาส่วนทรัพยากร Dependency ใน package.json แล้วแทนที่ด้วยส่วนต่อไปนี้
package.json
"dependencies": {
"firebase": "^9.0.0"
}
ติดตั้งการอ้างอิงอีกครั้ง
เนื่องจากเราเปลี่ยนเวอร์ชันของ Dependency จึงต้องเรียกใช้ npm install อีกครั้งเพื่อรับ Dependency เวอร์ชันใหม่
เปลี่ยนเส้นทางการนำเข้า
แพ็กเกจความเข้ากันได้จะแสดงในโมดูลย่อย 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. อัปเกรดการตรวจสอบสิทธิ์เพื่อใช้ API แบบแยกส่วน
คุณอัปเกรดผลิตภัณฑ์ Firebase ได้ตามลำดับใดก็ได้ ใน Codelab นี้ คุณจะอัปเกรด 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';
- นำ
Userออกจากimport { firebaseAuth, User } from './firebase';เนื่องจากคุณได้นำเข้าUserจาก‘firebase/auth'.แล้ว - อัปเดตฟังก์ชันเพื่อใช้ API แบบแยกส่วน
ดังที่คุณได้เห็นไปแล้วก่อนหน้านี้เมื่อเราอัปเดตคำสั่งนำเข้า แพ็กเกจในเวอร์ชัน 9 จะจัดระเบียบตามฟังก์ชันที่คุณนำเข้าได้ ซึ่งแตกต่างจาก API ของเวอร์ชัน 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
- เปลี่ยนไปที่แท็บเครือข่าย
- รีเฟรชหน้าเว็บเพื่อบันทึกคำขอเครือข่าย
- มองหา main.js และตรวจสอบขนาด คุณลดขนาด Bundle ลงได้ 100 KB (36 KB เมื่อบีบอัดด้วย gzip) หรือเล็กลงประมาณ 22% เพียงแค่เปลี่ยนโค้ด 2-3 บรรทัด นอกจากนี้ เว็บไซต์ยังโหลดเร็วขึ้น 0.75 วินาทีเมื่อใช้การเชื่อมต่อ 3G ที่ช้า

6. อัปเกรดแอป Firebase และ Firestore เพื่อใช้ Modular API
อัปเดตการเริ่มต้น 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()
อัปเดต addToWatchList()
ใช้ doc() เพื่อสร้างการอ้างอิงเอกสารไปยังรายการที่อยากดูของผู้ใช้ จากนั้นเพิ่ม Ticker ลงในเอกสารโดยใช้ 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 });
}
อัปเดต deleteFromWatchList()
ในทำนองเดียวกัน ให้นำหุ้นออกจากรายการที่อยากดูของผู้ใช้โดยใช้ setDoc() กับ 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 });
}
อัปเดต 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
- เปลี่ยนไปที่แท็บเครือข่าย
- รีเฟรชหน้าเว็บเพื่อบันทึกคำขอเครือข่าย
- มองหา
main.jsแล้วตรวจสอบขนาด เปรียบเทียบกับขนาด Bundle เดิมอีกครั้ง เราได้ลดขนาด Bundle ลงกว่า 200 KB (63.8 KB เมื่อบีบอัดด้วย gzip) หรือเล็กลง 50% ซึ่งทำให้เวลาในการโหลดเร็วขึ้น 1.3 วินาที

7. ใช้ Firestore Lite เพื่อเพิ่มความเร็วในการแสดงผลหน้าเว็บครั้งแรก
Firestore Lite คืออะไร
Firestore SDK มีแคชที่ซับซ้อน การสตรีมแบบเรียลไทม์ ที่เก็บข้อมูลแบบถาวร การซิงค์แบบออฟไลน์ในหลายแท็บ การลองใหม่ การทำงานพร้อมกันแบบมองโลกในแง่ดี และอื่นๆ อีกมากมาย จึงมีขนาดค่อนข้างใหญ่ แต่คุณอาจต้องการรับข้อมูลเพียงครั้งเดียวโดยไม่ต้องใช้ฟีเจอร์ขั้นสูง สำหรับกรณีดังกล่าว Firestore ได้สร้างโซลูชันที่เรียบง่ายและมีขนาดเล็ก ซึ่งก็คือแพ็กเกจใหม่ล่าสุดอย่าง Firestore Lite
กรณีการใช้งานที่ยอดเยี่ยมอย่างหนึ่งของ Firestore Lite คือการเพิ่มประสิทธิภาพการแสดงหน้าเว็บครั้งแรก ซึ่งคุณเพียงแค่ต้องทราบว่าผู้ใช้เข้าสู่ระบบหรือไม่ จากนั้นอ่านข้อมูลบางอย่างจาก Firestore เพื่อแสดง
ในขั้นตอนนี้ คุณจะได้เรียนรู้วิธีใช้ Firestore Lite เพื่อลดขนาด Bundle เพื่อเร่งการแสดงหน้าเว็บครั้งแรก จากนั้นโหลด Firestore SDK หลักแบบไดนามิกเพื่อสมัครรับข้อมูลอัปเดตแบบเรียลไทม์
คุณจะปรับโครงสร้างโค้ดเพื่อทำสิ่งต่อไปนี้
- ย้ายบริการแบบเรียลไทม์ไปยังไฟล์แยกต่างหากเพื่อให้โหลดแบบไดนามิกได้โดยใช้การนำเข้าแบบไดนามิก
- สร้างฟังก์ชันใหม่เพื่อใช้ Firestore Lite ในการดึงข้อมูลรายการติดตามและราคาหุ้น
- ใช้ฟังก์ชัน Firestore Lite ใหม่เพื่อดึงข้อมูลมาแสดงหน้าเว็บครั้งแรก จากนั้นโหลดบริการแบบเรียลไทม์แบบไดนามิกเพื่อฟังการอัปเดตแบบเรียลไทม์
ย้ายบริการแบบเรียลไทม์ไปยังไฟล์ใหม่
- สร้างไฟล์ใหม่ชื่อ
src/services.realtime.ts. - ย้ายฟังก์ชัน
subscribeToTickerChanges()และsubscribeToAllTickerChanges()จากsrc/services.tsไปยังไฟล์ใหม่ - เพิ่มการนำเข้าที่จำเป็นที่ด้านบนของไฟล์ใหม่
คุณยังคงต้องทำการเปลี่ยนแปลง 2-3 อย่างที่นี่
- ก่อนอื่น ให้สร้างอินสแตนซ์ Firestore จาก Firestore SDK หลักที่ด้านบนของไฟล์ที่จะใช้ในฟังก์ชัน คุณไม่สามารถนําเข้าอินสแตนซ์ Firestore จาก
firebase.tsที่นี่ได้เนื่องจากคุณจะเปลี่ยนเป็นอินสแตนซ์ Firestore Lite ในอีกไม่กี่ขั้นตอน ซึ่งจะใช้สําหรับการแสดงหน้าเว็บครั้งแรกเท่านั้น - ประการที่ 2 ให้นำตัวแปร
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. - คุณจะต้องใช้ฟังก์ชันที่สร้างขึ้นใหม่เพื่อดึงข้อมูลสำหรับการแสดงหน้าเว็บครั้งแรก และฟังก์ชันตัวช่วย 2-3 รายการเพื่อจัดการสถานะของแอป ตอนนี้ให้อัปเดตการนำเข้าดังนี้
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
- เปลี่ยนไปที่แท็บเครือข่าย
- รีเฟรชหน้าเว็บเพื่อบันทึกคำขอเครือข่าย
- มองหา
main.jsแล้วตรวจสอบขนาด - ตอนนี้มีขนาดเพียง 115 KB (34.5 KB เมื่อบีบอัดด้วย gzip) ซึ่งเล็กกว่าขนาด Bundle เดิมถึง 75% ซึ่งมีขนาด 446 KB(138 KB เมื่อบีบอัดด้วย Gzip) ด้วยเหตุนี้ เว็บไซต์จึงโหลดได้เร็วกว่าเดิม 2 วินาทีเมื่อเชื่อมต่อ 3G ซึ่งเป็นการปรับปรุงประสิทธิภาพและประสบการณ์ของผู้ใช้ที่ยอดเยี่ยม

8. ขอแสดงความยินดี
ขอแสดงความยินดี คุณอัปเกรดแอปสำเร็จแล้ว ทำให้แอปมีขนาดเล็กลงและเร็วขึ้น
คุณใช้แพ็กเกจความเข้ากันได้เพื่ออัปเกรดแอปทีละส่วน และใช้ Firestore Lite เพื่อเร่งการแสดงหน้าเว็บครั้งแรก จากนั้นโหลด Firestore หลักแบบไดนามิกเพื่อสตรีมการเปลี่ยนแปลงราคา
นอกจากนี้ คุณยังลดขนาดของแพ็กเกจและปรับปรุงเวลาในการโหลดใน Codelab นี้ด้วย
main.js | ขนาดทรัพยากร (KB) | ขนาดที่บีบอัดด้วย gzip (kb) | เวลาที่ใช้ในการโหลด (วินาที) (ผ่าน 3G ที่ช้า) |
v8 | 446 | 138 | 4.92 |
v9 compat | 429 | 124 | 4.65 |
การตรวจสอบสิทธิ์แบบแยกส่วน v9 เท่านั้น | 348 | 102 | 4.2 |
v9 แบบแยกส่วนทั้งหมด | 244 | 74.6 | 3.66 |
v9 fully modular + Firestore lite | 117 | 34.9 | 2.88 |

ตอนนี้คุณทราบขั้นตอนสำคัญที่จำเป็นในการอัปเกรดเว็บแอปที่ใช้ Firebase JS SDK เวอร์ชัน 8 ให้ใช้ JS SDK แบบแยกส่วนใหม่แล้ว