1- قبل البدء
إنّ حزمة Firebase JS SDK المكوّنة من وحدات هي إعادة كتابة لحزمة JS SDK الحالية، وسيتم إصدارها كإصدار رئيسي جديد. وتتيح هذه الحزمة للمطوّرين استبعاد الرموز غير المستخدَمة من حزمة تطوير البرامج (SDK) لـ Firebase JS من أجل إنشاء حِزم أصغر وتحقيق أداء أفضل.
يتمثل الاختلاف الأكثر وضوحًا في حزمة SDK المكوّنة من وحدات JavaScript في أنّ الميزات يتم تنظيمها الآن في وظائف عائمة حرة ستستوردها، بدلاً من استخدام مساحة اسم firebase
واحدة تتضمّن كل شيء. تتيح هذه الطريقة الجديدة لتنظيم الرموز البرمجية إحداث اهتزاز في الأشجار، وستتعرف على كيفية ترقية أي تطبيق يستخدم حاليًا الإصدار 8 من حزمة JavaScript JS من Firebase إلى الإصدار النموذجي الجديد.
لتسهيل عملية الترقية، يتم توفير مجموعة من حِزم التوافق. في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية استخدام حِزم التوافق لنقل التطبيق جزءًا تلو الآخر.
التطبيق الذي ستصممه
في هذا الدليل التعليمي حول الرموز البرمجية، ستنقل تدريجيًا تطبيق ويب حاليًا يتضمّن قائمة مراقبة الأسهم ويستخدم حزمة تطوير البرامج (SDK) لإصدار 8 من JavaScript إلى حزمة تطوير البرامج (SDK) الجديدة والمكوّنة من وحدات لإصدار JavaScript في ثلاث مراحل:
- ترقية التطبيق لاستخدام حِزم التوافق
- ترقية التطبيق من حِزم التوافق إلى واجهة برمجة التطبيقات المُركّبة تدريجيًا
- استخدام Firestore Lite، وهو إصدار خفيف من حزمة تطوير البرامج (SDK) لمنصة Firestore، لتحسين أداء التطبيق بشكلٍ أكبر
تركّز ورشة رموز البرامج هذه على ترقية حزمة تطوير البرامج (SDK) لمنصّة Firebase. يتمّ التقليل من أهمية المفاهيم الأخرى ووحدات الرموز البرمجية، ويتمّ تقديمها لك لكي تتمكّن من نسخها ولصقها بسهولة.
المتطلبات
2- الإعداد
الحصول على الرمز
يمكنك العثور على كل ما تحتاجه لهذا المشروع في مستودع Git. للبدء، يجب جلب الرمز وفتحه في بيئة تطوير البرامج المفضّلة لديك.
استنسِخ مستودع Github الخاص ببرنامج التعليم البرمجي من سطر الأوامر:
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- وضع خط أساس
ما هي نقطة البداية؟
نقطة البداية هي تطبيق قائمة أسهم مصمَّم لهذا الدرس التطبيقي حول الترميز. تم تبسيط الرمز لشرح المفاهيم الواردة في هذا الدليل التعليمي حول الرموز البرمجية، ولا يتضمّن الكثير من عمليات معالجة الأخطاء. إذا اخترت إعادة استخدام أيّ من هذا الرمز في تطبيق علني، تأكَّد من معالجة أيّ أخطاء واختبار كلّ الرمز البرمجي بالكامل.
تأكَّد من أنّ كل العناصر تعمل في التطبيق:
- سجِّل الدخول بشكل مجهول باستخدام زر تسجيل الدخول في أعلى يسار الصفحة.
- بعد تسجيل الدخول، ابحث عن "NFLX" و"SBUX" و "T" وأضِفها إلى قائمة المشاهدة من خلال النقر على الزر إضافة وكتابة الأحرف والنقر على صف نتائج البحث الذي يظهر أدناه.
- أزِل سهمًا من قائمة المراقبة بالنقر على x في نهاية الصف.
- اطّلِع على آخر المعلومات في الوقت الفعلي عن سعر السهم.
- افتح "أدوات مطوّري البرامج في Chrome"، وانتقِل إلى علامة التبويب الشبكة وضَع علامة في المربّع بجانب إيقاف ذاكرة التخزين المؤقت واستخدام صفوف طلبات كبيرة. يضمن خيار إيقاف ذاكرة التخزين المؤقت تلقّي أحدث التغييرات دائمًا بعد التحديث، ويؤدي خيار استخدام صفوف طلبات كبيرة إلى عرض كلّ من الحجم المُرسَل وحجم المرجع لمرجع معيّن. في هذا الدرس التطبيقي حول الترميز، نحن مهتمون بشكل أساسي بحجم
main.js
.
- تحميل التطبيق في ظل ظروف مختلفة للشبكة باستخدام ميزة "تقييد المحاكاة" ستستخدم شبكة الجيل الثالث (3G) البطيئة لقياس وقت التحميل في هذا الدليل التعليمي لأنّه يُظهر بوضوح مدى أهمية تقليل حجم الحِزمة.
انتقِل الآن إلى التطبيق وانقله إلى واجهة برمجة التطبيقات modular API الجديدة.
4. استخدام حِزم التوافق
تتيح لك حِزم التوافق الترقية إلى إصدار حزمة تطوير البرامج (SDK) الجديد بدون تغيير كل رمز Firebase دفعةً واحدة. ويمكنك ترقيتها إلى واجهة برمجة التطبيقات المكوّنة من وحدات تدريجيًا.
في هذه الخطوة، ستُجري ترقية لـ مكتبة Firebase من الإصدار 8 إلى الإصدار الجديد وستغيّر الرمز البرمجي لاستخدام حِزم التوافق. في الخطوات التالية، ستتعرّف على كيفية ترقية رمز 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 API بسيطة نسبيًا. تُعد ترقية Firestore عملية أكثر تعقيدًا، وستتعرف على كيفية إجراء ذلك بعد ذلك.
تعديل إعدادات Auth initialization
- الانتقال إلى الملف
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'.
- عدِّل الدوال لاستخدام modular API.
كما رأيت سابقًا عند تعديل عبارة الاستيراد، يتم تنظيم الحِزم في الإصدار 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".
- انتقِل إلى علامة التبويب الشبكة.
- يُرجى إعادة تحميل الصفحة لتسجيل طلبات الشبكة.
- ابحث عن main.js وتحقّق من حجمه. لقد خفضت حجم الحزمة بمقدار 100 كيلوبايت (36 كيلوبايت مضغوط بتنسيق gzip)، أي ما يعادل 22% تقريبًا من خلال تغيير بضعة أسطر من الرمز البرمجي فقط. يتم أيضًا تحميل الموقع الإلكتروني بشكل أسرع بمقدار 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()
للاطّلاع على الرمز المكتمل.
تعديل addToWatchList()
استخدِم doc()
لإنشاء إشارة مرجعية لمستند إلى قائمة المراقبة الخاصة بالمستخدم، ثم أضِف رمز سهم باستخدام 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);
});
يُرجى الاطّلاع على followToTickerChanges() عملية التنفيذ بالكامل.
تعديل 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
وتحقّق من حجمه. قارِن ذلك بحجم الحزمة الأصلي مرة أخرى. لقد خفّضنا حجم الحزمة بأكثر من 200 كيلوبايت (63.8 كيلوبايت مضغوط بتنسيق gzip)، أو بنسبة% 50، ما يُقلّل وقت التحميل بمقدار 1.3 ثانية.
7- استخدام Firestore Lite لتسريع عرض الصفحة الأولي
ما هو Firestore Lite؟
توفّر حزمة تطوير البرامج (SDK) لـ Firestore ميزات معقدة، مثل التخزين المؤقت والبث المباشر في الوقت الفعلي والتخزين الدائم والمزامنة بلا إنترنت في علامات تبويب متعددة وإعادة المحاولة والمزامنة التفاؤلية وغير ذلك الكثير، وبالتالي فإنّ حجمها كبير جدًا. ولكن قد تحتاج إلى الحصول على البيانات مرة واحدة فقط، بدون الحاجة إلى أي من الميزات المتقدّمة. في هذه الحالات، أنشأت Firestore حلًا بسيطًا وخفيفًا، وهو حزمة جديدة تمامًا تُعرف باسم Firestore Lite.
إنّ إحدى حالات الاستخدام الرائعة في Firestore Lite هي تحسين أداء العرض الأولي للصفحة، حيث تحتاج فقط إلى معرفة ما إذا كان المستخدم قد سجّل الدخول أم لا، ثم قراءة بعض البيانات من Firetore لعرضها.
في هذه الخطوة، ستتعرّف على كيفية استخدام Firestore lite لتقليل حجم الحِزمة من أجل تسريع عرض الصفحة الأولي، ثم تحميل حزمة تطوير البرامج (SDK) الرئيسية لـ Firestore ديناميكيًا للاشتراك في التعديلات في الوقت الفعلي.
ستعيد صياغة الرمز البرمجي لإجراء ما يلي:
- نقل الخدمات في الوقت الفعلي إلى ملف منفصل، حتى يمكن تحميلها ديناميكيًا باستخدام الاستيراد الديناميكي
- أنشئ دوال جديدة لاستخدام Firestore Lite لاسترداد قائمة المراقبة وأسعار الأسهم.
- استخدِم وظائف Firestore Lite الجديدة لاسترداد البيانات من أجل عرض الصفحة الأولية، ثم تحميل الخدمات في الوقت الفعلي بشكل ديناميكي للاستماع إلى آخر الأخبار في الوقت الفعلي.
نقل الخدمات في الوقت الفعلي إلى ملف جديد
- إنشاء ملف جديد باسم
src/services.realtime.ts.
- انقل الدالتَين
subscribeToTickerChanges()
وsubscribeToAllTickerChanges()
منsrc/services.ts
إلى الملف الجديد. - أضِف عمليات الاستيراد اللازمة إلى أعلى الملف الجديد.
لا يزال عليك إجراء بعض التغييرات هنا:
- أولاً، أنشئ مثيل Firestore من حزمة Firestore SDK الرئيسية أعلى الملف ليتم استخدامه في الدوال. لا يمكنك استيراد مثيل Firestore من
firebase.ts
هنا لأنك سيتم تغييره إلى مثيل 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".
- انتقِل إلى علامة التبويب الشبكة.
- يُرجى إعادة تحميل الصفحة لتسجيل طلبات الشبكة.
- ابحث عن
main.js
وتحقّق من حجمه. - والآن أصبح حجمها 115 كيلوبايت فقط (34.5 كيلوبايت مضغوط بتنسيق gzip). وهذا الحجم أصغر بنسبة% 75 من حجم الحزمة الأصلية الذي كان 446 كيلوبايت(138 كيلوبايت مضغوط بتنسيق gzip). ونتيجة لذلك، يتم تحميل الموقع بشكل أسرع باستخدام اتصال شبكة الجيل الثالث (3G)، ما يقدم أداءً رائعًا وتحسينًا لتجربة المستخدم.
8- تهانينا
تهانينا، لقد قمت بترقية التطبيق بنجاح وجعله أصغر حجمًا وأسرع!
لقد استخدمت الحزم المتوافقة لترقية التطبيق على مراحل، واستخدمت Firestore Lite لتسريع عرض الصفحة الأولية، ثم حمَّلت إصدار Firestore الرئيسي ديناميكيًا للاطّلاع على التغييرات في الأسعار.
لقد خفضت أيضًا حجم الحزمة وحسّنت مدة تحميلها على مدار هذا الدليل التعليمي حول الرموز البرمجية:
main.js | حجم الموارد (كيلوبايت) | الحجم المضغوط (كيلوبايت) | مدّة التحميل (بالثواني) (عبر شبكة الجيل الثالث البطيئة) |
الإصدار 8 | 446 | 138 | 4.92 |
التوافق مع الإصدار 9 | 429 | 124 | 4.65 |
المصادقة المُركّبة في الإصدار 9 فقط | 348 | 102 | 4.2 |
الإصدار 9 من الوحدات بالكامل | 244 | 74.6 | 3.66 |
الإصدار 9 من الوحدات بالكامل + Firestore lite | 117 | 34.9 | 2.88 |
أصبحت على دراية الآن بالخطوات الأساسية المطلوبة لترقية تطبيق ويب يستخدِم الإصدار 8 من حزمة تطوير البرامج (SDK) لـ Firebase JS من أجل استخدام حزمة تطوير البرامج (SDK) المعيارية الجديدة.