Cloudflare এর হাতেখড়ি (পর্ব ১১) – Caching ও Performance অপটিমাইজেশন

Cloudflare Caching ও Performance অপটিমাইজেশন

পর্ব ৮-এ KV দিয়ে ম্যানুয়ালি ক্যাশিং করেছিলাম। কিন্তু Cloudflare-এর একটা আরও সরাসরি টুল আছে এই কাজের জন্য — Cache API, যা পুরো HTTP রেসপন্স ক্যাশ করে, আর Cache-Control হেডার, যা ব্রাউজার ও Cloudflare-এর নিজস্ব CDN-কে বলে দেয় কতক্ষণ কিছু ক্যাশ রাখতে হবে। এই পর্বে শিখব কীভাবে সাইট দ্রুত করা যায় প্র্যাকটিক্যালি।

তিন স্তরের ক্যাশিং

একটা রিকোয়েস্ট যখন আসে, তিনটা জায়গায় ক্যাশ চেক হতে পারে —

  1. ব্রাউজার ক্যাশ — ইউজারের নিজের ডিভাইসে সেভ থাকে, দ্বিতীয়বার একই সাইটে এলে নেটওয়ার্কই লাগে না
  2. Cloudflare Edge Cache (CDN) — Cloudflare-এর কাছের সার্ভারে সেভ থাকে, অরিজিন সার্ভার পর্যন্ত যাওয়া লাগে না
  3. Worker-এর নিজস্ব Cache API / KV — কোডের ভেতর ম্যানুয়ালি নিয়ন্ত্রণ করা ক্যাশ (পর্ব ৮-এর মতো)

Cache-Control হেডার — বেসিক

যেকোনো রেসপন্সে একটা হেডার যোগ করে বলে দেওয়া যায় কতক্ষণ ক্যাশ রাখতে হবে।

export default {
  async fetch(request, env, ctx) {
    const data = { books: ["অপরাজিত", "পথের পাঁচালী"] };

    return new Response(JSON.stringify(data), {
      headers: {
        "content-type": "application/json",
        "Cache-Control": "public, max-age=300", // ৫ মিনিট ক্যাশ
      },
    });
  },
};

এখানে public মানে যে কেউ (ব্রাউজার, Cloudflare CDN) ক্যাশ করতে পারবে, max-age=300 মানে ৩০০ সেকেন্ড (৫ মিনিট) পর্যন্ত ক্যাশ বৈধ।

কোন কনটেন্টে কেমন Cache-Control

কনটেন্ট টাইপ উদাহরণ প্রস্তাবিত
ছবি, ফন্ট, CSS/JS বান্ডেল book-cover.jpg max-age=31536000, immutable (১ বছর)
ব্লগ পোস্ট, স্ট্যাটিক পেজ /blog/firebase-part-1 max-age=3600 (১ ঘণ্টা)
প্রায়ই বদলানো API ডেটা /api/books max-age=60 (১ মিনিট)
ইউজার-নির্দিষ্ট, সেনসিটিভ /api/my-profile private, no-store (ক্যাশ না করা)

immutable মানে — এই ফাইলের কনটেন্ট কখনো বদলাবে না (সাধারণত ফাইলের নামে একটা hash যোগ করে এটা নিশ্চিত করা হয়, যেমন app.a1b2c3.js), তাই ব্রাউজার এমনকি রিফ্রেশ চেকও করবে না।

Worker-এর Cache API — নিজে থেকে ক্যাশ ব্যবস্থাপনা

শুধু হেডার সেট করার বাইরে, Worker কোড থেকেই সরাসরি ক্যাশ চেক ও সেভ করা যায় — পর্ব ৮-এর KV-ভিত্তিক ক্যাশিং-এর চেয়ে এটা হেডারসহ পুরো রেসপন্স সেভ করে।

export default {
  async fetch(request, env, ctx) {
    const cache = caches.default;
    const cacheKey = new Request(request.url, request);

    // প্রথমে ক্যাশে আছে কিনা দেখা
    let response = await cache.match(cacheKey);
    if (response) {
      return response; // ক্যাশ থেকে সরাসরি ফেরত
    }

    // না থাকলে আসল ডেটা তৈরি করা
    const data = { books: ["অপরাজিত"] };
    response = new Response(JSON.stringify(data), {
      headers: {
        "content-type": "application/json",
        "Cache-Control": "public, max-age=300",
      },
    });

    // ক্যাশে সেভ করা (ব্যাকগ্রাউন্ডে, রেসপন্স আটকে না রেখে)
    ctx.waitUntil(cache.put(cacheKey, response.clone()));

    return response;
  },
};

লক্ষ্য করুন — response.clone() ব্যবহার হচ্ছে, কারণ একটা Response একবারই পড়া যায় — একই রেসপন্স ইউজারকে পাঠানো আর ক্যাশে সেভ করা দুটোর জন্যই আলাদা কপি লাগে। ctx.waitUntil() Worker-কে বলে দেয় — রেসপন্স পাঠানোর পরও ব্যাকগ্রাউন্ডে ক্যাশ সেভের কাজ শেষ করতে দাও।

Cache Purge — জোর করে পুরনো ক্যাশ মুছে ফেলা

ধরা যাক একটা বইয়ের তথ্য আপডেট হয়েছে, কিন্তু পুরনো ক্যাশড ভার্সন এখনো দেখাচ্ছে। Cloudflare Dashboard থেকে ম্যানুয়ালি purge করা যায় —

  1. Caching → Configuration → Purge Cache-এ যান
  2. Custom Purge দিয়ে নির্দিষ্ট URL, অথবা Purge Everything দিয়ে সব মুছে ফেলা যায়

প্রোগ্রাম্যাটিকভাবেও API দিয়ে purge করা যায় — যেমন একটা বই আপডেট হলে GitHub Actions ওয়ার্কফ্লো থেকেই (পর্ব ২) স্বয়ংক্রিয়ভাবে সেই URL-এর ক্যাশ পার্জ করে দেওয়া।

অন্যান্য Performance টিপস

  • ছবি অপটিমাইজেশন — Cloudflare-এর Image Resizing/Polish ফিচার দিয়ে ছবি স্বয়ংক্রিয়ভাবে সংকুচিত ও সঠিক ফরম্যাটে (WebP) পরিবেশন করা যায়
  • Brotli/Gzip কম্প্রেশন — Cloudflare ডিফল্টভাবেই টেক্সট-ভিত্তিক কনটেন্ট (HTML, CSS, JS) কম্প্রেস করে পাঠায়, বাড়তি কিছু করতে হয় না
  • HTTP/3 ও QUIC — Cloudflare স্বয়ংক্রিয়ভাবে সাপোর্ট করে, দ্রুততর কানেকশনের জন্য

ইন্টারেক্টিভ — Cache Hit রেসপন্স টাইম

নিচে দেখো ভিন্ন ভিন্ন max-age সেটিং কীভাবে বারবার রিকোয়েস্টের গড় রেসপন্স টাইম কমায়।

ভালো অভ্যাস

  • ইউজার-নির্দিষ্ট ডেটা কখনো পাবলিকভাবে ক্যাশ করবেন নাprivate বা no-store ব্যবহার করুন, নাহলে একজনের ডেটা আরেকজন দেখে ফেলতে পারে
  • স্ট্যাটিক অ্যাসেটে দীর্ঘ ক্যাশ + ফাইলনামে hash — আপডেট হলে ফাইলের নাম বদলে যায়, তাই পুরনো ক্যাশ সমস্যা করে না
  • যতটা সম্ভব দীর্ঘ max-age ব্যবহার করুন যেখানে ডেটা কম বদলায়, কিন্তু কখনো "খুব বেশি নিরাপদ থাকতে" ছোট max-age রাখারও দরকার নেই যদি Purge API ব্যবহারের সুযোগ থাকে

নিজে চেষ্টা করো

Exercise:

  1. নিজের Worker-এ একটা রেসপন্সে Cache-Control: public, max-age=60 যোগ করো, ব্রাউজার DevTools-এর Network ট্যাবে গিয়ে হেডার চেক করো।
  2. উপরের Cache API প্যাটার্ন দিয়ে একটা Worker বানাও, প্রথমবার আর দ্বিতীয়বার রিকোয়েস্টের সময় তুলনা করো।
  3. Cloudflare Dashboard-এ গিয়ে একটা নির্দিষ্ট URL-এর ক্যাশ ম্যানুয়ালি Purge করো।
  4. নিজের কোনো প্রজেক্টের বিভিন্ন কনটেন্ট (ছবি, API, পেজ) তালিকা করে প্রতিটার জন্য উপযুক্ত max-age ঠিক করো।

পরের পর্বে যা থাকছে

পরের পর্বে আমরা শিখব Security — Rate Limiting ও WAF বেসিক — কীভাবে বট বা অতিরিক্ত রিকোয়েস্ট থেকে নিজের API সুরক্ষিত রাখা যায়, আর Cloudflare-এর Web Application Firewall কীভাবে কাজ করে।

একটি মন্তব্য পোস্ট করুন

নবীনতর পূর্বতন

যোগাযোগ ফর্ম