با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
بسیاری از برنامه ها محتوای یکسانی را در بارگذاری صفحه اول به همه کاربران ارائه می دهند. به عنوان مثال یک سایت خبری ممکن است آخرین داستان ها را نشان دهد، یا یک سایت تجارت الکترونیک ممکن است موارد پرفروش را نشان دهد.
اگر این محتوا از Cloud Firestore ارائه شود، هر کاربر هنگام بارگیری برنامه، یک درخواست جدید برای نتایج یکسان صادر می کند. از آنجایی که این نتایج بین کاربران ذخیره نمیشوند، برنامه کندتر و گرانتر از آن چیزی است که باید باشد.
راه حل: بسته نرم افزاری
بستههای Cloud Firestore به شما این امکان را میدهند که بستههای داده را از نتایج جستجوی رایج در پشتیبان با استفاده از Firebase Admin SDK جمعآوری کنید و این حبابهای از پیش محاسبهشده را در حافظه پنهان در یک CDN ارائه دهید. این به کاربران شما تجربه بارگیری اولیه بسیار سریعتری را میدهد و هزینههای جستجوی Cloud Firestore شما را کاهش میدهد.
در این راهنما Cloud Functions برای تولید بستهها و Firebase Hosting برای ذخیرهسازی پویا و ارائه محتوای بسته استفاده میکنیم. اطلاعات بیشتر در مورد بسته ها در راهنماها موجود است.
ابتدا یک تابع HTTP عمومی ساده ایجاد کنید تا 50 آخرین "داستان" را پرس و جو کنید و نتیجه را به عنوان یک بسته ارائه کنید.
Node.js
exports.createBundle=functions.https.onRequest(async(request,response)=>{// Query the 50 latest storiesconstlatestStories=awaitdb.collection('stories').orderBy('timestamp','desc').limit(50).get();// Build the bundle from the query resultsconstbundleBuffer=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-cacheresponse.set('Cache-Control','public, max-age=300, s-maxage=600');response.end(bundleBuffer);});
جاوا
packagecom.example;importcom.google.auth.oauth2.GoogleCredentials;importcom.google.cloud.firestore.Firestore;importcom.google.cloud.firestore.FirestoreBundle;importcom.google.cloud.firestore.Query.Direction;importcom.google.cloud.firestore.QuerySnapshot;importcom.google.cloud.functions.HttpFunction;importcom.google.cloud.functions.HttpRequest;importcom.google.cloud.functions.HttpResponse;importcom.google.firebase.FirebaseApp;importcom.google.firebase.FirebaseOptions;importcom.google.firebase.cloud.FirestoreClient;importjava.io.BufferedWriter;importjava.io.IOException;publicclassExampleFunctionimplementsHttpFunction{publicstaticFirebaseAppinitializeFirebase()throwsIOException{if(FirebaseApp.getApps().isEmpty()){FirebaseOptionsoptions=FirebaseOptions.builder().setCredentials(GoogleCredentials.getApplicationDefault()).setProjectId("YOUR-PROJECT-ID").build();FirebaseApp.initializeApp(options);}returnFirebaseApp.getInstance();}@Overridepublicvoidservice(HttpRequestrequest,HttpResponseresponse)throwsException{// Get a Firestore instanceFirebaseAppapp=initializeFirebase();Firestoredb=FirestoreClient.getFirestore(app);// Query the 50 latest storiesQuerySnapshotlatestStories=db.collection("stories").orderBy("timestamp",Direction.DESCENDING).limit(50).get().get();// Build the bundle from the query resultsFirestoreBundlebundle=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-cacheresponse.appendHeader("Cache-Control","public, max-age=300, s-maxage=600");// Write the bundle to the HTTP responseBufferedWriterwriter=response.getWriter();writer.write(newString(bundle.toByteBuffer().array()));}}
سپس Firebase Hosting را پیکربندی کنید تا با تغییر firebase.json این تابع Cloud را ارائه و ذخیره کند. با این پیکربندی، Firebase Hosting CDN محتوای بسته را مطابق تنظیمات حافظه پنهان تنظیم شده توسط Cloud Function ارائه می کند. هنگامی که حافظه پنهان منقضی شود، با فعال کردن مجدد تابع، محتوا را تازه می کند.
در نهایت در برنامه وب خود، محتوای همراه را از CDN واکشی کنید و آن را در Firestore SDK بارگیری کنید.
// If you are using module bundlers.importfirebasefrom"firebase/app";import"firebase/firestore";import"firebase/firestore/bundle"// This line enables bundle loading as a side effect.asyncfunctionfetchFromBundle(){// Fetch the bundle from Firebase Hosting, if the CDN cache is hit the 'X-Cache'// response header will be set to 'HIT'constresp=awaitfetch('/createBundle');// Load the bundle contents into the Firestore SDKawaitdb.loadBundle(resp.body);// Query the results from the cache// Note: omitting "source: cache" will query the Firestore backend.constquery=awaitdb.namedQuery('latest-stories-query');conststoriesSnap=awaitquery.get({source:'cache'});// Use the results// ...}
پس انداز تخمینی
یک وب سایت خبری را در نظر بگیرید که روزانه 100000 کاربر دریافت می کند و هر کاربر همان 50 خبر برتر را در بارگذاری اولیه بارگذاری می کند. بدون هیچ گونه ذخیره سازی، این امر منجر به 50 x 100،000 = 5،000،000 خواندن سند در روز از Cloud Firestore می شود.
حال فرض کنید سایت تکنیک بالا را اتخاذ کرده و آن 50 نتیجه را حداکثر تا 5 دقیقه در حافظه پنهان نگه می دارد. بنابراین به جای بارگیری نتایج پرس و جو برای هر کاربر، نتایج دقیقاً 12 بار در ساعت بارگذاری می شوند. مهم نیست که چند کاربر به سایت وارد می شوند، تعداد پرس و جوها به Cloud Firestore ثابت می ماند. به جای 5,000,000 خواندن سند، این صفحه از 12 x 24 x 50 = 14,400 خواندن سند در روز استفاده می کند. هزینه های اضافی کوچک برای میزبانی Firebase و Cloud Functions به راحتی با صرفه جویی در هزینه Cloud Firestore جبران می شود.
در حالی که توسعه دهنده از صرفه جویی در هزینه سود می برد، بزرگترین ذینفع، کاربر است. بارگیری این 50 سند از CDN میزبانی Firebase به جای مستقیماً از Cloud Firestore می تواند به راحتی 100-200 میلی ثانیه یا بیشتر از زمان بارگذاری محتوای صفحه را حذف کند. مطالعات بارها نشان داده اند که صفحات سریع به معنای کاربران شادتر است.
تاریخ آخرین بهروزرسانی 2025-09-04 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-09-04 بهوقت ساعت هماهنگ جهانی."],[],[],null,["\u003cbr /\u003e\n\nMany applications serve the same content to all users on first page load. For\nexample a news site may show the latest stories, or an e-commerce site may show\nthe best-selling items.\n\nIf this content is served from Cloud Firestore, each user will issue a new\nquery for the same results when they load the application. Because these\nresults are not cached between users, the application is slower and more\nexpensive than it needs to be.\n\nSolution: Bundles\n\nCloud Firestore bundles allow you to assemble data bundles from common query\nresults on the backend using the Firebase Admin SDK, and serve these\npre-computed blobs cached on a CDN. This gives your users a much\nfaster first load experience and reduces your Cloud Firestore query costs.\n\nIn this guide we will use Cloud Functions to generate bundles and\nFirebase Hosting to dynamically cache and serve bundle content. More\ninformation about bundles is available in the [guides](/docs/firestore/bundles).\n\nFirst create a simple public HTTP function to query the 50 latest \"stories\" and\nserve the result as a bundle. \n\nNode.js \n\n```javascript\nexports.createBundle = functions.https.onRequest(async (request, response) =\u003e {\n // Query the 50 latest stories\n const latestStories = await db.collection('stories')\n .orderBy('timestamp', 'desc')\n .limit(50)\n .get();\n\n // Build the bundle from the query results\n const bundleBuffer = db.bundle('latest-stories')\n .add('latest-stories-query', latestStories)\n .build();\n\n // Cache the response for up to 5 minutes;\n // see https://firebase.google.com/docs/hosting/manage-cache\n response.set('Cache-Control', 'public, max-age=300, s-maxage=600');\n\n response.end(bundleBuffer);\n});\n \n```\n\nJava \n\n```java\n\npackage com.example;\n\nimport com.google.auth.oauth2.GoogleCredentials;\nimport com.google.cloud.firestore.Firestore;\nimport com.google.cloud.firestore.FirestoreBundle;\nimport com.google.cloud.firestore.Query.Direction;\nimport com.google.cloud.firestore.QuerySnapshot;\nimport com.google.cloud.functions.HttpFunction;\nimport com.google.cloud.functions.HttpRequest;\nimport com.google.cloud.functions.HttpResponse;\nimport com.google.firebase.FirebaseApp;\nimport com.google.firebase.FirebaseOptions;\nimport com.google.firebase.cloud.FirestoreClient;\nimport java.io.BufferedWriter;\nimport java.io.IOException;\n\npublic class ExampleFunction implements HttpFunction {\n\n public static FirebaseApp initializeFirebase() throws IOException {\n if (FirebaseApp.getApps().isEmpty()) {\n FirebaseOptions options = FirebaseOptions.builder()\n .setCredentials(GoogleCredentials.getApplicationDefault())\n .setProjectId(\"YOUR-PROJECT-ID\")\n .build();\n\n FirebaseApp.initializeApp(options);\n }\n\n return FirebaseApp.getInstance();\n }\n\n @Override\n public void service(HttpRequest request, HttpResponse response) throws Exception {\n // Get a Firestore instance\n FirebaseApp app = initializeFirebase();\n Firestore db = FirestoreClient.getFirestore(app);\n\n // Query the 50 latest stories\n QuerySnapshot latestStories = db.collection(\"stories\")\n .orderBy(\"timestamp\", Direction.DESCENDING)\n .limit(50)\n .get()\n .get();\n\n // Build the bundle from the query results\n FirestoreBundle bundle = db.bundleBuilder(\"latest-stores\")\n .add(\"latest-stories-query\", latestStories)\n .build();\n\n // Cache the response for up to 5 minutes\n // see https://firebase.google.com/docs/hosting/manage-cache\n response.appendHeader(\"Cache-Control\", \"public, max-age=300, s-maxage=600\");\n\n // Write the bundle to the HTTP response\n BufferedWriter writer = response.getWriter();\n writer.write(new String(bundle.toByteBuffer().array()));\n }\n}\n \n```\n\nNext configure Firebase Hosting to serve and cache this Cloud Function by\nmodifying `firebase.json`. With this configuration the Firebase Hosting CDN\nwill serve the bundle content according to the cache settings set by the\nCloud Function. When the cache expires it will refresh the content by triggering\nthe function again. \n\n firebase.json\n {\n \"hosting\": {\n // ...\n \"rewrites\": [{\n \"source\": \"/createBundle\",\n \"function\": \"createBundle\"\n }]\n },\n // ...\n }\n\nFinally in your web application, fetch the bundled content from the CDN and load\nit into the Firestore SDK. \n\n // If you are using module bundlers.\n import firebase from \"firebase/app\";\n import \"firebase/firestore\";\n import \"firebase/firestore/bundle\" // This line enables bundle loading as a side effect.\n\n async function fetchFromBundle() {\n // Fetch the bundle from Firebase Hosting, if the CDN cache is hit the 'X-Cache'\n // response header will be set to 'HIT'\n const resp = await fetch('/createBundle');\n\n // Load the bundle contents into the Firestore SDK\n await db.loadBundle(resp.body);\n\n // Query the results from the cache\n // Note: omitting \"source: cache\" will query the Firestore backend.\n \n const query = await db.namedQuery('latest-stories-query');\n const storiesSnap = await query.get({ source: 'cache' });\n\n // Use the results\n // ...\n }\n\nEstimated Savings\n\nConsider a news website which gets 100,000 users per day and each user loads the\nsame 50 top stories on initial load. Without any caching, this would result in\n50 x 100,000 = 5,000,000 document reads per day from Cloud Firestore.\n\nNow assume the site adopts the technique above and caches those 50 results for\nup to 5 minutes. So instead of loading the query results for every user, the\nresults are loaded exactly 12 times per hour. No matter how many users arrive\nat the site, the number of queries to Cloud Firestore stays the same. Instead of\n5,000,000 document reads, this page would use 12 x 24 x 50 = 14,400 document\nreads per day. The small additional costs for Firebase Hosting and\nCloud Functions are easily offset by the Cloud Firestore cost savings.\n\nWhile the developer benefits from the cost savings, the biggest beneficiary is\nthe user. Loading these 50 documents from the Firebase Hosting CDN rather than\nfrom Cloud Firestore directly can easily shave 100-200ms or more from the\ncontent load time of the page. Studies have repeatedly shown that speedy pages\nmean happier users."]]