Birçok uygulama, ilk sayfa yüklemesinde tüm kullanıcılara aynı içeriği sunar. Örneğin, bir haber sitesi en son haberleri gösterebilir veya bir e-ticaret sitesi gösterilebilir en çok satan öğeleri içerir.
Bu içerik Cloud Firestore hizmetinden sunulursa her kullanıcı yeni bir sorgu gönderir. Çünkü bunlar sonuçlar kullanıcılar arasında önbelleğe alınmaz, uygulama daha yavaş ve daha pahalıya mal olabilir.
Çözüm: Paketler
Cloud Firestore paketleri, ortak sorgudan veri paketleri oluşturmanıza olanak tanır arka uçta gösterilen sonuçları alıp bu sonuçları CDN'de önbelleğe alınmış önceden hesaplanmış blob'lar. Bu sayede, kullanıcılarınıza daha hızlı ilk yükleme deneyimi sunar ve Cloud Firestore sorgu maliyetlerinizi azaltır.
Bu kılavuzda Cloud Functions'ı kullanarak paket ve Grup içeriğini dinamik olarak önbelleğe almak ve yayınlamak için Firebase Hosting. Daha fazla Paketlerle ilgili bilgileri kılavuzlarda bulabilirsiniz.
Öncelikle son 50 "hikayeyi" sorgulamak için basit bir herkese açık HTTP işlevi oluşturun ve sonucu bir paket olarak sunar.
Node.js
exports.createBundle = functions.https.onRequest(async (request, response) => { // Query the 50 latest stories const latestStories = await db.collection('stories') .orderBy('timestamp', 'desc') .limit(50) .get(); // Build the bundle from the query results const bundleBuffer = db.bundle('latest-stories') .add('latest-stories-query', latestStories) .build(); // Cache the response for up to 5 minutes; // see https://firebase.google.com/docs/hosting/manage-cache response.set('Cache-Control', 'public, max-age=300, s-maxage=600'); response.end(bundleBuffer); });
Java
package com.example; import com.google.auth.oauth2.GoogleCredentials; import com.google.cloud.firestore.Firestore; import com.google.cloud.firestore.FirestoreBundle; import com.google.cloud.firestore.Query.Direction; import com.google.cloud.firestore.QuerySnapshot; import com.google.cloud.functions.HttpFunction; import com.google.cloud.functions.HttpRequest; import com.google.cloud.functions.HttpResponse; import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.cloud.FirestoreClient; import java.io.BufferedWriter; import java.io.IOException; public class ExampleFunction implements HttpFunction { public static FirebaseApp initializeFirebase() throws IOException { if (FirebaseApp.getApps().isEmpty()) { FirebaseOptions options = FirebaseOptions.builder() .setCredentials(GoogleCredentials.getApplicationDefault()) .setProjectId("YOUR-PROJECT-ID") .build(); FirebaseApp.initializeApp(options); } return FirebaseApp.getInstance(); } @Override public void service(HttpRequest request, HttpResponse response) throws Exception { // Get a Firestore instance FirebaseApp app = initializeFirebase(); Firestore db = FirestoreClient.getFirestore(app); // Query the 50 latest stories QuerySnapshot latestStories = db.collection("stories") .orderBy("timestamp", Direction.DESCENDING) .limit(50) .get() .get(); // Build the bundle from the query results FirestoreBundle bundle = db.bundleBuilder("latest-stores") .add("latest-stories-query", latestStories) .build(); // Cache the response for up to 5 minutes // see https://firebase.google.com/docs/hosting/manage-cache response.appendHeader("Cache-Control", "public, max-age=300, s-maxage=600"); // Write the bundle to the HTTP response BufferedWriter writer = response.getWriter(); writer.write(new String(bundle.toByteBuffer().array())); } }
Ardından Firebase Hosting'i, bu Cloud Functions işlevini aşağıdaki şekilde sunmak ve önbelleğe alacak şekilde yapılandırın:
firebase.json
değiştiriliyor. Bu yapılandırmayla Firebase Hosting CDN'si
Google Etiket Yöneticisi tarafından belirlenen önbellek ayarlarına göre
Cloud Functions işlevi görür. Önbelleğin süresi dolduğunda
işlevi tekrar tıklayın.
firebase.json
{
"hosting": {
// ...
"rewrites": [{
"source": "/createBundle",
"function": "createBundle"
}]
},
// ...
}
Son olarak web uygulamanızda, gruplandırılmış içeriği CDN'den alın ve yükleyin bunu Firestore SDK'ya aktarmanızı sağlar.
// If you are using module bundlers.
import firebase from "firebase/app";
import "firebase/firestore";
import "firebase/firestore/bundle" // This line enables bundle loading as a side effect.
async function fetchFromBundle() {
// Fetch the bundle from Firebase Hosting, if the CDN cache is hit the 'X-Cache'
// response header will be set to 'HIT'
const resp = await fetch('/createBundle');
// Load the bundle contents into the Firestore SDK
await db.loadBundle(resp.body);
// Query the results from the cache
// Note: omitting "source: cache" will query the Firestore backend.
const query = await db.namedQuery('latest-stories-query');
const storiesSnap = await query.get({ source: 'cache' });
// Use the results
// ...
}
Tahmini Tasarruf Miktarı
Günde 100.000 kullanıcıya ulaşan ve her kullanıcının ilk yüklemede, en çok okunan 50 haberi görmeye başlarsınız. Herhangi bir önbelleğe alma olmadan, Cloud Firestore tarihinden itibaren 50 x 100.000 = 5.000.000 belge okuma işlemi.
Şimdi sitenin yukarıdaki tekniği kullandığını ve bu 50 sonucu önceden önbelleğe aldığını en fazla 5 dakika sürer. Yani her kullanıcı için sorgu sonuçlarını yüklemek yerine sonuçları saatte tam olarak 12 kez yüklenir. Kaç kullanıcı gelirse gelsin Cloud Firestore'a gönderilen sorguların sayısı aynı kalıyor. Şunun yerine: 5.000.000 belge okuma, bu sayfa 12 x 24 x 50 = 14.400 belge kullanır okuma sayısı. Firebase Hosting ve Cloud Functions, Cloud Firestore olan maliyet tasarrufu sayesinde kolayca dengelenebilir.
Maliyet tasarrufları geliştiriciye fayda sağlasa da en büyük fayda sağlayan taraf; gösterir. Bu 50 dokümanı Firebase Hosting CDN'den yüklemek yerine tıraşınızı doğrudan Cloud Firestore'den 100-200 ms veya daha fazla yükleme süresini ölçer. Araştırmalar, hızlı sayfaların hızlı daha mutlu kullanıcılar demektir.