قم بتعزيز تطبيق الويب الخاص بك عن طريق الانتقال إلى Firebase JS SDK المعياري

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، لتحسين أداء التطبيق بشكل أكبر

2d351cb47b604ad7.png

يركز هذا الدرس التطبيقي حول التعليمات البرمجية على ترقية Firebase SDK. يتم تلميع المفاهيم وكتل التعليمات البرمجية الأخرى ويتم توفيرها لك ببساطة للنسخ واللصق.

ماذا ستحتاج

  • متصفح من اختيارك، مثل Chrome
  • محرر IDE/النصوص الذي تختاره، مثل WebStorm أو Atom أو Sublime أو VS Code
  • مدير الحزم npm ، والذي يأتي عادةً مع Node.js
  • نموذج التعليمات البرمجية الخاص ببرنامج Codelab (راجع الخطوة التالية من برنامج Codelab للتعرف على كيفية الحصول على التعليمات البرمجية.)

2. قم بالإعداد

احصل على الرمز

كل ما تحتاجه لهذا المشروع موجود في Git repo. للبدء، ستحتاج إلى الحصول على الكود وفتحه في بيئة التطوير المفضلة لديك.

قم باستنساخ مستودع Github الخاص بـ Codelab من سطر الأوامر:

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

وبدلاً من ذلك، إذا لم يكن git مثبتًا لديك، فيمكنك تنزيل المستودع كملف ZIP وفك ضغط الملف المضغوط الذي تم تنزيله.

قم باستيراد التطبيق

  1. باستخدام IDE الخاص بك، افتح أو قم باستيراد دليل codelab-modular-sdk .
  2. قم بتشغيل npm install لتثبيت التبعيات المطلوبة لإنشاء التطبيق وتشغيله محليًا.
  3. قم بتشغيل npm run build لإنشاء التطبيق.
  4. قم بتشغيل npm run serve لبدء تشغيل خادم الويب
  5. افتح علامة تبويب المتصفح على http://localhost:8080

71a8a7d47392e8f4.png

3. إنشاء خط الأساس

ما هي نقطة البداية الخاصة بك؟

نقطة البداية هي تطبيق قائمة مراقبة الأسهم المُصمم لهذا الدرس التطبيقي حول التعليمات البرمجية. لقد تم تبسيط التعليمات البرمجية لتوضيح المفاهيم الواردة في هذا الدرس التطبيقي حول التعليمات البرمجية، كما أنها تحتوي على قدر ضئيل من معالجة الأخطاء. إذا اخترت إعادة استخدام أي من هذه التعليمات البرمجية في تطبيق الإنتاج، فتأكد من معالجة أي أخطاء واختبار كافة التعليمات البرمجية بشكل كامل.

تأكد من أن كل شيء يعمل في التطبيق:

  1. قم بتسجيل الدخول بشكل مجهول باستخدام زر تسجيل الدخول في الزاوية اليمنى العليا.
  2. بعد تسجيل الدخول، ابحث عن "NFLX" و"SBUX" و"T" وأضفها إلى قائمة المراقبة عن طريق النقر فوق الزر " إضافة " وكتابة الحروف والنقر فوق صف نتيجة البحث المنبثق أدناه.
  3. قم بإزالة السهم من قائمة المراقبة عن طريق النقر فوق علامة x في نهاية الصف.
  4. مشاهدة التحديثات في الوقت الحقيقي لسعر السهم.
  5. افتح Chrome DevTools، وانتقل إلى علامة التبويب "الشبكة" وحدد تعطيل ذاكرة التخزين المؤقت واستخدام صفوف الطلبات الكبيرة . يؤدي تعطيل ذاكرة التخزين المؤقت إلى التأكد من أننا نحصل دائمًا على أحدث التغييرات بعد التحديث واستخدام صفوف الطلب الكبيرة يجعل الصف يعرض كلاً من الحجم المرسل وحجم المورد للمورد. في هذا الدرس التطبيقي حول التعليمات البرمجية، نهتم بشكل أساسي بحجم الملف main.js

48a096debb2aa940.png

  1. قم بتحميل التطبيق في ظل ظروف شبكة مختلفة باستخدام محاكاة الاختناق. ستستخدم Slow 3G لقياس وقت التحميل في هذا الدرس التطبيقي حول الترميز لأنه المكان الذي يساعد فيه حجم الحزمة الأصغر كثيرًا.

4397cb2c1327089.png

انتقل الآن وابدأ في ترحيل التطبيق إلى واجهة برمجة التطبيقات المعيارية الجديدة.

4. استخدم حزم التوافق

تسمح لك حزم التوافق بالترقية إلى إصدار SDK الجديد دون تغيير كود Firebase بالكامل مرة واحدة. يمكنك ترقيتها إلى واجهة برمجة التطبيقات المعيارية تدريجيًا.

في هذه الخطوة، ستقوم بترقية مكتبة Firebase من الإصدار 8 إلى الإصدار الجديد وتغيير التعليمات البرمجية لاستخدام حزم التوافق. في الخطوات التالية، ستتعرف على كيفية ترقية كود Firebase Auth فقط لاستخدام واجهة برمجة التطبيقات المعيارية أولاً، ثم ترقية كود Firestore.

في نهاية كل خطوة، يجب أن تكون قادرًا على تجميع التطبيق وتشغيله دون انقطاع، وملاحظة انخفاض في حجم الحزمة أثناء ترحيل كل منتج.

احصل على SDK الجديد

ابحث عن قسم التبعيات في package.json واستبدله بما يلي:

package.json

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

أعد تثبيت التبعيات

نظرًا لأننا قمنا بتغيير إصدار التبعية، فنحن بحاجة إلى إعادة تشغيل npm install للحصول على الإصدار الجديد من التبعية.

تغيير مسارات الاستيراد

يتم عرض حزم التوافق ضمن الوحدة الفرعية firebase/compat ، لذلك سنقوم بتحديث مسارات الاستيراد وفقًا لذلك:

  1. انتقل إلى الملف src/firebase.ts
  2. استبدل الواردات الحالية بالواردات التالية:

src/firebase.ts

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

التحقق من عمل التطبيق

  1. قم بتشغيل npm run build لإعادة بناء التطبيق.
  2. افتح علامة تبويب المتصفح على http://localhost:8080 ، أو قم بتحديث علامة التبويب الحالية.
  3. العب مع التطبيق. كل شيء يجب أن يظل يعمل.

5. قم بترقية المصادقة لاستخدام واجهة برمجة التطبيقات المعيارية

يمكنك ترقية منتجات Firebase بأي ترتيب. في هذا الدرس التطبيقي حول التعليمات البرمجية، ستقوم بترقية Auth أولاً لتتعلم المفاهيم الأساسية لأن واجهة برمجة تطبيقات Auth بسيطة نسبيًا. تعد ترقية Firestore أكثر تعقيدًا، وسوف تتعلم كيفية القيام بذلك بعد ذلك.

تحديث تهيئة المصادقة

  1. انتقل إلى الملف src/firebase.ts
  2. أضف الاستيراد التالي:

src/firebase.ts

import { initializeAuth, indexedDBLocalPersistence } from 'firebase/auth';
  1. احذف import 'firebase/compat/auth'.
  2. استبدل export const firebaseAuth = app.auth(); مع:

src/firebase.ts

export const firebaseAuth = initializeAuth(app, { persistence: [indexedDBLocalPersistence] });
  1. إزالة export type User = firebase.User; في نهاية الملف. سيتم تصدير User مباشرة إلى src/auth.ts والذي ستقوم بتغييره بعد ذلك.

تحديث رمز المصادقة

  1. انتقل إلى الملف src/auth.ts
  2. أضف الواردات التالية إلى أعلى الملف:

src/auth.ts

import { 
    signInAnonymously, 
    signOut,
    onAuthStateChanged,
    User
} from 'firebase/auth';
  1. إزالة User من import { firebaseAuth, User } from './firebase'; نظرًا لأنك قمت بالفعل باستيراد User من 'firebase/auth'.
  2. قم بتحديث الوظائف لاستخدام واجهة برمجة التطبيقات المعيارية.

كما رأيت سابقًا عندما قمنا بتحديث بيان الاستيراد، يتم تنظيم الحزم في الإصدار 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';

التحقق من عمل التطبيق

  1. قم بتشغيل npm run build لإعادة بناء التطبيق.
  2. افتح علامة تبويب المتصفح على http://localhost:8080 ، أو قم بتحديث علامة التبويب الحالية
  3. العب مع التطبيق. كل شيء يجب أن يظل يعمل.

تحقق من حجم الحزمة

  1. افتح أدوات تطوير Chrome.
  2. قم بالتبديل إلى علامة التبويب "الشبكة" .
  3. قم بتحديث الصفحة لالتقاط طلبات الشبكة.
  4. ابحث عن main.js وتحقق من حجمه. لقد قمت بتقليل حجم الحزمة بمقدار 100 كيلو بايت (36 كيلو بايت مضغوطة بصيغة gzipped)، أو أصغر بنسبة 22% تقريبًا عن طريق تغيير بضعة أسطر فقط من التعليمات البرمجية! يقوم الموقع أيضًا بتحميل أسرع بمقدار 0.75 ثانية على اتصال 3G بطيء.

2e4eafaf66cd829b.png

6. قم بترقية تطبيق Firebase وFirestore لاستخدام واجهة برمجة التطبيقات المعيارية

تحديث تهيئة Firebase

  1. انتقل إلى الملف src/firebase.ts.
  2. استبدل import firebase from 'firebase/compat/app'; مع:

src/firebase.ts

import { initializeApp } from 'firebase/app';
  1. استبدل 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.appspot.com", 
    messagingSenderId: "875614679042", 
    appId: "1:875614679042:web:5813c3e70a33e91ba0371b"
});

تحديث تهيئة Firestore

  1. في نفس الملف src/firebase.ts, استبدل import 'firebase/compat/firestore'; مع

src/firebase.ts

import { getFirestore } from 'firebase/firestore';
  1. استبدل export const firestore = app.firestore(); مع:

src/firebase.ts

export const firestore = getFirestore();
  1. قم بإزالة جميع الأسطر بعد " export const firestore = ... "

تحديث الواردات

  1. افتح الملف src/services.ts.
  2. قم بإزالة FirestoreFieldPath و FirestoreFieldValue و QuerySnapshot من عملية الاستيراد. يجب أن يبدو الاستيراد من './firebase' الآن كما يلي:

src/services.ts

import { firestore } from './firebase';
  1. قم باستيراد الوظائف والأنواع التي ستستخدمها في الجزء العلوي من الملف:
    **src/services.ts**
import { 
    collection, 
    getDocs, 
    doc, 
    setDoc, 
    arrayUnion, 
    arrayRemove, 
    onSnapshot, 
    query, 
    where, 
    documentId, 
    QuerySnapshot
} from 'firebase/firestore';
  1. قم بإنشاء مرجع للمجموعة التي تحتوي على كافة المؤشرات:

src/services.ts

const tickersCollRef = collection(firestore, 'current');
  1. استخدم 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 });
}

تحديث الإشتراك في ToTickerChanges()

  1. استخدم doc() لإنشاء مرجع مستند إلى قائمة مراقبة المستخدم أولاً، ثم استمع إلى تغييرات قائمة المراقبة باستخدام onSnapshot() :

src/services.ts

const watchlistRef = doc(firestore, `watchlist/${user.uid}`);
const unsubscribe = onSnapshot(watchlistRef, snapshot => {
   /* subscribe to ticker price changes */
});
  1. بمجرد حصولك على المؤشرات في قائمة المراقبة، استخدم 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 للتنفيذ الكامل.

تحديث الاشتراك في AllTickerChanges()

ستستخدم أولاً 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);
   });
}

التحقق من عمل التطبيق

  1. قم بتشغيل npm run build لإعادة بناء التطبيق.
  2. افتح علامة تبويب المتصفح على http://localhost:8080 ، أو قم بتحديث علامة التبويب الحالية
  3. العب مع التطبيق. كل شيء يجب أن يظل يعمل.

تحقق من حجم الحزمة

  1. افتح أدوات تطوير Chrome.
  2. قم بالتبديل إلى علامة التبويب "الشبكة" .
  3. قم بتحديث الصفحة لالتقاط طلبات الشبكة.
  4. ابحث عن main.js وتحقق من حجمه. قارنها بحجم الحزمة الأصلية مرة أخرى - لقد قمنا بتقليل حجم الحزمة بأكثر من 200 كيلو بايت (63.8 كيلو بايت مضغوطة)، أو أصغر بنسبة 50%، مما يعني وقت تحميل أسرع بمقدار 1.3 ثانية!

7660cdc574ee8571.png

7. استخدم Firestore Lite لتسريع عرض الصفحة الأولية

ما هو فايرستور لايت؟

يوفر Firestore SDK تخزينًا مؤقتًا معقدًا، وتدفقًا في الوقت الفعلي، وتخزينًا مستمرًا، ومزامنة متعددة علامات التبويب في وضع عدم الاتصال، وإعادة المحاولة، والتزامن المتفائل، وغير ذلك الكثير، وبالتالي فهو كبير جدًا في الحجم. ولكن قد ترغب ببساطة في الحصول على البيانات مرة واحدة، دون الحاجة إلى أي من الميزات المتقدمة. بالنسبة لهذه الحالات، أنشأت Firestore حلاً بسيطًا وخفيفًا، وهي حزمة جديدة تمامًا - Firestore Lite.

إحدى حالات الاستخدام الرائعة لـ Firestore Lite هي تحسين أداء العرض الأولي للصفحة، حيث تحتاج فقط إلى معرفة ما إذا كان المستخدم قد قام بتسجيل الدخول أم لا، ثم قراءة بعض البيانات من Firetore لعرضها.

في هذه الخطوة، ستتعلم كيفية استخدام Firestore lite لتقليل حجم الحزمة لتسريع العرض الأولي للصفحة، ثم تحميل Firestore SDK الرئيسي ديناميكيًا للاشتراك في التحديثات في الوقت الفعلي.

سوف تقوم بإعادة بناء الكود إلى:

  1. انقل خدمات الوقت الفعلي إلى ملف منفصل، بحيث يمكن تحميلها ديناميكيًا باستخدام الاستيراد الديناميكي.
  2. قم بإنشاء وظائف جديدة لاستخدام Firestore Lite لاسترداد قائمة المراقبة وأسعار الأسهم.
  3. استخدم وظائف Firestore Lite الجديدة لاسترداد البيانات لإجراء العرض الأولي للصفحة، ثم قم بتحميل الخدمات في الوقت الفعلي ديناميكيًا للاستماع إلى التحديثات في الوقت الفعلي.

نقل الخدمات في الوقت الحقيقي إلى ملف جديد

  1. قم بإنشاء ملف جديد يسمى src/services.realtime.ts.
  2. انقل الدالتين subscribeToTickerChanges() و subscribeToAllTickerChanges() من src/services.ts إلى الملف الجديد.
  3. أضف الواردات الضرورية إلى أعلى الملف الجديد.

لا تزال بحاجة إلى إجراء بعض التغييرات هنا:

  1. أولاً، قم بإنشاء مثيل 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 لجلب البيانات

  1. افتح ملف src/services.ts.
  2. قم بتغيير مسار الاستيراد من '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';
  1. أضف وظائف لجلب البيانات اللازمة لعرض الصفحة الأولي باستخدام 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. افتح src/firebase.ts ، وقم بتغيير مسار الاستيراد من 'firebase/firestore' إلى 'firebase/firestore/lite':

src/firebase.ts

import { getFirestore } from 'firebase/firestore/lite';

اربطهم جميعًا معًا

  1. افتح ملف src/main.ts.
  2. ستحتاج إلى الوظائف التي تم إنشاؤها حديثًا لجلب البيانات للعرض الأولي للصفحة، بالإضافة إلى وظيفتين مساعدتين لإدارة حالة التطبيق. والآن قم بتحديث الواردات:

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. قم بتحميل src/services.realtime باستخدام استيراد ديناميكي في أعلى الملف. يعد loadRealtimeService المتغير وعدًا سيتم حله مع خدمات الوقت الفعلي بمجرد تحميل الكود. ستستخدمه لاحقًا للاشتراك في التحديثات في الوقت الفعلي.

src/main.ts

const loadRealtimeService = import('./services.realtime');
loadRealtimeService.then(() => {
   setRealtimeServicesLoaded(true);
});
  1. قم بتغيير رد الاتصال الخاص بـ onUserChange() إلى دالة async ، حتى نتمكن من استخدام await في نص الوظيفة:

src/main.ts

onUserChange(async user => {
 // callback body
});
  1. الآن قم بإحضار البيانات لعرض الصفحة الأولية باستخدام الوظائف الجديدة التي أنشأناها في الخطوة السابقة.

في رد الاتصال 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   
   }
}
  1. في الكتلة الأخرى التي لم يقم فيها أي مستخدم بتسجيل الدخول، قم بإحضار معلومات الأسعار لجميع الأسهم باستخدام 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 للتعرف على الكود النهائي.

التحقق من عمل التطبيق

  1. قم بتشغيل npm run build لإعادة بناء التطبيق.
  2. افتح علامة تبويب المتصفح على http://localhost:8080 ، أو قم بتحديث علامة التبويب الحالية.

تحقق من حجم الحزمة

  1. افتح أدوات تطوير Chrome.
  2. قم بالتبديل إلى علامة التبويب "الشبكة" .
  3. قم بتحديث الصفحة لالتقاط طلبات الشبكة
  4. ابحث عن main.js وتحقق من حجمه.
  5. الآن يبلغ حجمه 115 كيلو بايت فقط (34.5 كيلو بايت مضغوطًا بواسطة gzp). وهذا أصغر بنسبة 75% من حجم الحزمة الأصلية التي كانت 446 كيلو بايت (138 كيلو بايت مضغوطة بواسطة gzipped)! ونتيجة لذلك، يتم تحميل الموقع بشكل أسرع بما يزيد عن ثانيتين على اتصال 3G - وهو أداء رائع وتحسين تجربة المستخدم!

9ea7398a8c8ef81b.png

8. تهانينا

تهانينا، لقد نجحت في ترقية التطبيق وجعله أصغر حجمًا وأسرع!

لقد استخدمت الحزم المتوافقة لترقية التطبيق قطعة قطعة، واستخدمت Firestore Lite لتسريع العرض الأولي للصفحة، ثم قمت بتحميل Firestore الرئيسي ديناميكيًا لدفق تغيرات الأسعار.

لقد قمت أيضًا بتقليل حجم الحزمة وتحسين وقت تحميلها على مدار هذا الدرس التطبيقي حول التعليمات البرمجية:

main.js

حجم المورد (كيلو بايت)

الحجم المضغوط (كيلو بايت)

وقت (فترات) التحميل (أكثر من 3G البطيء)

v8

446

138

4.92

متوافق مع الإصدار 9

429

124

4.65

v9 المصادقة المعيارية فقط

348

102

4.2

v9 وحدات بالكامل

244

74.6

3.66

الإصدار 9 المعياري بالكامل + Firestore lite

117

34.9

2.88

32a71bd5a774e035.png

أنت تعرف الآن الخطوات الأساسية المطلوبة لترقية تطبيق ويب يستخدم v8 Firebase JS SDK لاستخدام JS SDK المعياري الجديد.

قراءة متعمقة

المستندات المرجعية