একটি CDN থেকে বান্ডিল করা Firestore সামগ্রী পরিবেশন করুন

অনেক অ্যাপ্লিকেশন প্রথমবার পৃষ্ঠা লোড হওয়ার সময় সকল ব্যবহারকারীকে একই বিষয়বস্তু দেখায়। উদাহরণস্বরূপ, একটি সংবাদ সাইট সর্বশেষ খবরগুলো দেখাতে পারে, অথবা একটি ই-কমার্স সাইট সর্বাধিক বিক্রিত পণ্যগুলো প্রদর্শন করতে পারে।

যদি এই কন্টেন্টটি Cloud Firestore থেকে পরিবেশন করা হয়, তাহলে প্রত্যেক ব্যবহারকারী অ্যাপ্লিকেশনটি লোড করার সময় একই ফলাফলের জন্য একটি নতুন কোয়েরি চালাবেন। যেহেতু এই ফলাফলগুলো ব্যবহারকারীদের মধ্যে ক্যাশ করা থাকে না, তাই অ্যাপ্লিকেশনটি প্রয়োজনের চেয়ে ধীর এবং বেশি ব্যয়বহুল হয়ে পড়ে।

সমাধান: বান্ডিল

Cloud Firestore বান্ডেল আপনাকে ফায়ারবেস অ্যাডমিন এসডিকে ব্যবহার করে ব্যাকএন্ডে সাধারণ কোয়েরির ফলাফল থেকে ডেটা বান্ডেল তৈরি করতে এবং এই পূর্ব-গণনাকৃত ব্লবগুলিকে একটি সিডিএন-এ ক্যাশ করে পরিবেশন করতে দেয়। এটি আপনার ব্যবহারকারীদের অনেক দ্রুত প্রথম লোডের অভিজ্ঞতা দেয় এবং আপনার Cloud Firestore কোয়েরির খরচ কমিয়ে দেয়।

এই নির্দেশিকায় আমরা বান্ডেল তৈরি করতে Cloud Functions এবং বান্ডেলের বিষয়বস্তু ডায়নামিকভাবে ক্যাশ ও পরিবেশন করতে Firebase Hosting ব্যবহার করব। বান্ডেল সম্পর্কে আরও তথ্য নির্দেশিকাগুলোতে পাওয়া যাবে।

প্রথমে সর্বশেষ ৫০টি 'স্টোরি' কোয়েরি করার জন্য একটি সহজ পাবলিক HTTP ফাংশন তৈরি করুন এবং ফলাফলটি একটি বান্ডেল হিসেবে পরিবেশন করুন।

নোড.জেএস
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);
});
      
জাভা

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()));
  }
}
      

এরপর firebase.json পরিবর্তন করে এই ক্লাউড ফাংশনটি সার্ভ ও ক্যাশ করার জন্য ফায়ারবেস হোস্টিং কনফিগার করুন। এই কনফিগারেশনের মাধ্যমে Firebase Hosting সিডিএন, ক্লাউড ফাংশন দ্বারা সেট করা ক্যাশ সেটিংস অনুযায়ী বান্ডেল কন্টেন্ট সার্ভ করবে। ক্যাশের মেয়াদ শেষ হয়ে গেলে, এটি ফাংশনটিকে পুনরায় ট্রিগার করে কন্টেন্ট রিফ্রেশ করবে।

firebase.json
{
  "hosting": {
    // ...
    "rewrites": [{
      "source": "/createBundle",
      "function": "createBundle"
    }]
  },
  // ...
}

অবশেষে আপনার ওয়েব অ্যাপ্লিকেশনে, CDN থেকে বান্ডেল করা কন্টেন্টটি নিয়ে এসে Firestore SDK-তে লোড করুন।

// 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
  // ...
}

আনুমানিক সঞ্চয়

একটি সংবাদ ওয়েবসাইটের কথা ভাবুন যেখানে প্রতিদিন ১,০০,০০০ ব্যবহারকারী আসেন এবং প্রত্যেক ব্যবহারকারী ওয়েবসাইট চালু হওয়ার সাথে সাথেই একই ৫০টি সেরা খবর লোড করেন। কোনো ক্যাশিং ছাড়া, এর ফলে Cloud Firestore থেকে প্রতিদিন ৫০ x ১,০০,০০০ = ৫০,০০,০০০ ডকুমেন্ট রিড হবে।

এখন ধরে নিন, সাইটটি উপরের কৌশলটি অবলম্বন করে এবং ঐ ৫০টি ফলাফল ৫ মিনিট পর্যন্ত ক্যাশ করে রাখে। ফলে, প্রত্যেক ব্যবহারকারীর জন্য কোয়েরির ফলাফল লোড করার পরিবর্তে, ফলাফলগুলো প্রতি ঘণ্টায় ঠিক ১২ বার লোড হয়। সাইটে যত ব্যবহারকারীই আসুক না কেন, ক্লাউড ফায়ারস্টোরে কোয়েরির সংখ্যা একই থাকে। ৫০,০০,০০০ ডকুমেন্ট রিডের পরিবর্তে, এই পেজটি প্রতিদিন ১২ x ২৪ x ৫০ = ১৪,৪০০ ডকুমেন্ট রিড ব্যবহার করবে। ফায়ারবেস হোস্টিং এবং Cloud Functions জন্য যে সামান্য অতিরিক্ত খরচ হয়, তা Cloud Firestore খরচ সাশ্রয়ের মাধ্যমে সহজেই পুষিয়ে যায়।

যদিও ডেভেলপার খরচ সাশ্রয়ের ফলে লাভবান হন, তবে এর সবচেয়ে বড় সুবিধাভোগী হলেন ব্যবহারকারী। এই ৫০টি ডকুমেন্ট সরাসরি Cloud Firestore থেকে লোড না করে ফায়ারবেস হোস্টিং সিডিএন থেকে লোড করলে পেজের কন্টেন্ট লোড হওয়ার সময় সহজেই ১০০-২০০ মিলিসেকেন্ড বা তারও বেশি কমে যেতে পারে। গবেষণায় বারবার দেখা গেছে যে, দ্রুতগতির পেজ মানেই সন্তুষ্ট ব্যবহারকারী।