ব্যাক/ফরওয়ার্ড ক্যাশে

প্রকাশিত: ২৫ মে, ২০২৩, সর্বশেষ হালনাগাদ: ২ জুলাই, ২০২৬

ব্যাক/ফরোয়ার্ড ক্যাশে (বা বিএফক্যাশ) হলো একটি ব্রাউজার অপটিমাইজেশন যা তাৎক্ষণিক সামনে ও পেছনে যাওয়ার সুবিধা দেয়। এটি ব্রাউজিং অভিজ্ঞতাকে উল্লেখযোগ্যভাবে উন্নত করে, বিশেষ করে ধীরগতির নেটওয়ার্ক বা ডিভাইস ব্যবহারকারীদের জন্য।

ওয়েব ডেভেলপার হিসেবে, bfcache-এর জন্য আপনার পেজগুলোকে কীভাবে অপ্টিমাইজ করতে হয় তা বোঝা অত্যন্ত জরুরি, যাতে আপনার ব্যবহারকারীরা এর সুবিধাগুলো ভোগ করতে পারেন।

ব্রাউজার সামঞ্জস্যতা

ক্রোম ৯৬ সংস্করণ থেকে, ফায়ারফক্স এবং সাফারি সহ সকল প্রধান ব্রাউজারে একটি bfcache অন্তর্ভুক্ত থাকে।

বিএফক্যাশের মৌলিক বিষয়াবলী

ব্যাক/ফরোয়ার্ড ক্যাশে (bfcache) ব্যবহার করলে, ব্যবহারকারী অন্য পেজে চলে গেলে পেজটি মুছে ফেলার পরিবর্তে, আমরা সেই মুছে ফেলার প্রক্রিয়াটি স্থগিত রাখি এবং জাভাস্ক্রিপ্ট (JS) চালানো থামিয়ে দিই। যদি ব্যবহারকারী শীঘ্রই ফিরে আসেন, আমরা পেজটিকে আবার দৃশ্যমান করে তুলি এবং জাভাস্ক্রিপ্ট চালানো পুনরায় চালু করি। এর ফলে ব্যবহারকারী প্রায় সঙ্গে সঙ্গেই পেজে ফিরে যেতে পারেন।

কতবার এমন হয়েছে যে আপনি কোনো ওয়েবসাইটে গিয়ে অন্য পেজে যাওয়ার জন্য লিঙ্কে ক্লিক করেছেন, কিন্তু পরে বুঝতে পেরেছেন যে এটি আপনার কাঙ্ক্ষিত পেজ নয় এবং ব্যাক বাটনে ক্লিক করেছেন? সেই মুহূর্তে, আগের পেজটি কত দ্রুত লোড হবে, তাতে bfcache একটি বড় পার্থক্য গড়ে দিতে পারে।

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

নেভিগেশনে bfcache কতটা গতি বাড়াতে পারে তা বুঝতে এর কার্যকারিতার এই ভিডিওটি দেখুন:

bfcache ব্যবহার করলে সামনে ও পেছনে যাওয়ার সময় পেজগুলো অনেক দ্রুত লোড হয়।

ভিডিওটিতে, bfcache সহ উদাহরণটি এটি ছাড়া উদাহরণটির চেয়ে বেশ খানিকটা দ্রুততর।

bfcache শুধু নেভিগেশনের গতিই বাড়ায় না, এটি ডেটা ব্যবহারও কমায়, কারণ রিসোর্সগুলো পুনরায় ডাউনলোড করার প্রয়োজন হয় না।

ক্রোম ব্যবহারের ডেটা থেকে দেখা যায় যে, ডেস্কটপে প্রতি ১০টি নেভিগেশনের মধ্যে ১টি এবং মোবাইলে প্রতি ৫টি নেভিগেশনের মধ্যে ১টি হয় পেছনে যাওয়া অথবা সামনে যাওয়া। bfcache সক্রিয় থাকলে, ব্রাউজারগুলো প্রতিদিন শত শত কোটি ওয়েব পেজের জন্য প্রয়োজনীয় ডেটা ট্রান্সফার এবং লোড হওয়ার সময়কে সম্পূর্ণরূপে দূর করতে পারে!

"ক্যাশ" কীভাবে কাজ করে

bfcache যে "ক্যাশ" ব্যবহার করে তা HTTP ক্যাশ থেকে ভিন্ন, যা বারবার নেভিগেশনের গতি বাড়াতে নিজস্ব ভূমিকা পালন করে। bfcache হলো জাভাস্ক্রিপ্ট হিপ সহ মেমরিতে থাকা সম্পূর্ণ পেজটির একটি স্ন্যাপশট, যেখানে HTTP ক্যাশে শুধুমাত্র পূর্বে করা অনুরোধগুলোর প্রতিক্রিয়া থাকে। যেহেতু একটি পেজ লোড করার জন্য প্রয়োজনীয় সমস্ত অনুরোধ HTTP ক্যাশ থেকে পূরণ হওয়া খুবই বিরল, তাই bfcache রিস্টোর ব্যবহার করে বারবার ভিজিট করা এমনকি সবচেয়ে ভালোভাবে অপ্টিমাইজ করা নন-bfcache নেভিগেশনের চেয়েও সর্বদা দ্রুততর হয়।

পরবর্তীতে আবার চালু করার উদ্দেশ্যে কোনো পেজকে ফ্রিজ করার ক্ষেত্রে, চলমান কোড কীভাবে সবচেয়ে ভালোভাবে সংরক্ষণ করা যায়, সেই বিষয়ে কিছু জটিলতা রয়েছে। উদাহরণস্বরূপ, পেজটি bfcache-এ থাকা অবস্থায় টাইমআউট শেষ হয়ে গেলে setTimeout() কলগুলো আপনি কীভাবে সামলাবেন?

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

কিছু ক্ষেত্রে, যেমন টাইমআউট এবং প্রমিজের জন্য, এটি বেশ কম ঝুঁকিপূর্ণ, কিন্তু অন্যান্য ক্ষেত্রে এটি বিভ্রান্তিকর বা অপ্রত্যাশিত আচরণের কারণ হতে পারে। উদাহরণস্বরূপ, যদি ব্রাউজার এমন কোনো কাজ থামিয়ে দেয় যা একটি IndexedDB ট্রানজ্যাকশনের অংশ হিসেবে প্রয়োজন, তবে এটি একই অরিজিনে খোলা অন্যান্য ট্যাবকে প্রভাবিত করতে পারে, কারণ একই IndexedDB ডেটাবেস একাধিক ট্যাব দ্বারা একই সাথে অ্যাক্সেস করা যায়। ফলস্বরূপ, ব্রাউজারগুলো সাধারণত কোনো IndexedDB ট্রানজ্যাকশনের মাঝখানে বা এমন কোনো API ব্যবহার করার সময় পেজ ক্যাশ করার চেষ্টা করে না যা অন্য পেজকে প্রভাবিত করতে পারে।

বিভিন্ন API-এর ব্যবহার কীভাবে একটি পেজের bfcache যোগ্যতার উপর প্রভাব ফেলে, সে সম্পর্কে আরও বিস্তারিত জানতে, 'Optimize your pages for bfcache ' দেখুন।

বিএফক্যাশ এবং আইফ্রেম

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

তবে, যখন বিএফক্যাশ থেকে মূল ফ্রেমটি পুনরুদ্ধার করা হবে, তখন এমবেডেড আইফ্রেমগুলিও সেই অবস্থাতেই পুনরুদ্ধার হবে, যে অবস্থায় পৃষ্ঠাটি বিএফক্যাশে প্রবেশ করেছিল।

যদি কোনো এমবেডেড আইফ্রেম এমন এপিআই ব্যবহার করে যা বিএফক্যাশ (bfcache) ব্যবহারে বাধা দেয়, তাহলে মেইনফ্রেমের বিএফক্যাশ ব্যবহারও ব্লক হয়ে যেতে পারে। এটি এড়ানোর জন্য মেইনফ্রেমে পারমিশন পলিসি (Permissions Policy) সেট করা অথবা sandbox attributes) ব্যবহার করা যেতে পারে।

বিএফক্যাশ এবং সিঙ্গেল পেজ অ্যাপস (এসপিএ)

যেহেতু bfcache ব্রাউজার-পরিচালিত নেভিগেশনের সাথে কাজ করে, তাই এটি একটি সিঙ্গেল-পেজ অ্যাপ (SPA)-এর ভেতরের 'সফট নেভিগেশন'-এর জন্য কাজ করে না। তবে, অ্যাপটিকে আবার শুরু থেকে সম্পূর্ণভাবে পুনরায় চালু না করে, কোনো SPA-তে ফিরে যাওয়ার ক্ষেত্রেও bfcache সাহায্য করতে পারে।

bfcache পর্যবেক্ষণ করার জন্য API

যদিও বিএফক্যাশ (bfcache) একটি অপটিমাইজেশন যা ব্রাউজারগুলো স্বয়ংক্রিয়ভাবে করে থাকে, তবুও ডেভেলপারদের জন্য এটি কখন ঘটছে তা জানা গুরুত্বপূর্ণ, যাতে তারা এর জন্য তাদের পেজগুলো অপটিমাইজ করতে পারে এবং সেই অনুযায়ী যেকোনো মেট্রিক বা পারফরম্যান্স পরিমাপ সমন্বয় করতে পারে

bfcache পর্যবেক্ষণ করার জন্য ব্যবহৃত প্রধান ইভেন্টগুলো হলো pageshow এবং pagehide পেজ ট্রানজিশন ইভেন্ট , যেগুলো বেশিরভাগ ব্রাউজার দ্বারা সমর্থিত।

নতুন পেজ লাইফসাইকেল ইভেন্ট— freeze এবং resume —পেজ যখন bfcache-এ প্রবেশ করে বা তা থেকে বেরিয়ে যায়, তখন এবং আরও কিছু পরিস্থিতিতে, যেমন সিপিইউ ব্যবহার কমানোর জন্য যখন কোনো ব্যাকগ্রাউন্ড ট্যাব ফ্রিজ হয়ে যায়, তখনও ডিসপ্যাচ করা হয়। এই ইভেন্টগুলো শুধুমাত্র ক্রোমিয়াম-ভিত্তিক ব্রাউজারগুলিতে সমর্থিত।

bfcache থেকে কখন একটি পৃষ্ঠা পুনরুদ্ধার করা হয় তা পর্যবেক্ষণ করুন।

পেজটি প্রাথমিকভাবে লোড হওয়ার সময় এবং যখনই পেজটি বিএফক্যাশ (bfcache) থেকে রিস্টোর করা হয়, তখন load ইভেন্টের ঠিক পরেই pageshow ইভেন্টটি ফায়ার হয়। pageshow ইভেন্টের একটি persisted ) প্রপার্টি আছে, যা পেজটি বিএফক্যাশ থেকে রিস্টোর করা হলে ট্রু ( true এবং অন্যথায় false হয়। সাধারণ পেজ লোড এবং বিএফক্যাশ রিস্টোরের মধ্যে পার্থক্য করার জন্য আপনি persisted প্রপার্টিটি ব্যবহার করতে পারেন। উদাহরণস্বরূপ:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    console.log('This page was restored from the bfcache.');
  } else {
    console.log('This page was loaded normally.');
  }
});

যেসব ব্রাউজার পেজ লাইফসাইকেল এপিআই (Page Lifecycle API) সমর্থন করে, সেগুলোতে বিএফক্যাশ (bfcache) থেকে পেজ পুনরুদ্ধার করার সময় ( pageshow ইভেন্টের ঠিক আগে) এবং যখন কোনো ব্যবহারকারী একটি ফ্রোজেন (frozen) ব্যাকগ্রাউন্ড ট্যাবে পুনরায় প্রবেশ করে, তখন রেজিউম resume ) ইভেন্টটি ফায়ার হয়। যদি আপনি কোনো পেজ ফ্রোজেন হওয়ার পরে তার স্টেট আপডেট করতে চান (যার মধ্যে বিএফক্যাশে থাকা পেজগুলোও অন্তর্ভুক্ত), তাহলে আপনি resume ইভেন্টটি ব্যবহার করতে পারেন, কিন্তু যদি আপনি আপনার সাইটের বিএফক্যাশ হিট রেট (bfcache hit rate) পরিমাপ করতে চান, তাহলে আপনাকে pageshow ইভেন্টটি ব্যবহার করতে হবে। কিছু ক্ষেত্রে, আপনার উভয়ই ব্যবহার করার প্রয়োজন হতে পারে।

bfcache পরিমাপের সর্বোত্তম অনুশীলন সম্পর্কে বিস্তারিত জানতে, “bfcache কীভাবে অ্যানালিটিক্স এবং পারফরম্যান্স পরিমাপকে প্রভাবিত করে” দেখুন।

কখন একটি পৃষ্ঠা bfcache-এ প্রবেশ করছে তা পর্যবেক্ষণ করুন।

কোনো পৃষ্ঠা আনলোড হলে অথবা ব্রাউজার যখন সেটিকে বিএফক্যাশে (bfcache) রাখার চেষ্টা করে, তখন pagehide ইভেন্টটি ফায়ার হয়।

pagehide ইভেন্টের একটি persisted প্রপার্টিও আছে। যদি এর false , তবে আপনি নিশ্চিত থাকতে পারেন যে পেজটি bfcache-এ প্রবেশ করবে না। তবে, persisted এর মান true হলেই যে পেজটি ক্যাশ হবে, তার কোনো নিশ্চয়তা নেই। এর মানে হলো, ব্রাউজার পেজটি ক্যাশ করতে চায় , কিন্তু এমন অন্যান্য কারণও থাকতে পারে যার জন্য এটি ক্যাশ করা অসম্ভব হয়ে পড়ে।

window.addEventListener('pagehide', (event) => {
  if (event.persisted) {
    console.log('This page *might* be entering the bfcache.');
  } else {
    console.log('This page will unload normally and be discarded.');
  }
});

একইভাবে, যদি persisted true হয়, তাহলে pagehide ইভেন্টের ঠিক পরেই freeze ইভেন্টটি ফায়ার হয়, কিন্তু এর মানে শুধু এই যে ব্রাউজার পেজটি ক্যাশ করে রাখতে চায় । পরে ব্যাখ্যা করা বিভিন্ন কারণে ব্রাউজারকে পেজটি বাতিলও করে দিতে হতে পারে।

bfcache-এর জন্য আপনার পেজগুলো অপ্টিমাইজ করুন।

সব পেজ bfcache-এ সংরক্ষিত হয় না, এবং কোনো পেজ সেখানে সংরক্ষিত হলেও তা অনির্দিষ্টকালের জন্য সেখানে থাকে না। ডেভেলপারদের জন্য এটা বোঝা অত্যন্ত জরুরি যে কোন পেজগুলো bfcache-এর জন্য যোগ্য (এবং অযোগ্য) হয়, যাতে তারা তাদের ক্যাশ-হিট রেট সর্বোচ্চ করতে পারেন।

নিম্নলিখিত বিভাগগুলিতে এমন সেরা অনুশীলনগুলির রূপরেখা দেওয়া হয়েছে, যার মাধ্যমে ব্রাউজার আপনার পৃষ্ঠাগুলি ক্যাশ করার সম্ভাবনা যথাসম্ভব বাড়িয়ে তুলতে পারে।

unload ইভেন্টটি কখনই ব্যবহার করবেন না

সব ব্রাউজারে bfcache অপ্টিমাইজ করার সবচেয়ে গুরুত্বপূর্ণ উপায় হলো, কখনোই unload ইভেন্ট ব্যবহার না করা। কখনোই না!

ব্রাউজারগুলোর জন্য unload ইভেন্টটি একটি সমস্যা, কারণ এটি বিএফক্যাশ (bfcache)-এর আগের এবং ইন্টারনেটের অনেক পেজ এই (যৌক্তিক) ধারণার ওপর ভিত্তি করে চলে যে, unload ইভেন্টটি ফায়ার হওয়ার পর পেজটির অস্তিত্ব আর থাকবে না। এটি একটি প্রতিবন্ধকতা তৈরি করে, কারণ এই পেজগুলোর অনেকগুলোই এই ধারণার ওপর ভিত্তি করে তৈরি করা হয়েছিল যে, ব্যবহারকারী যখনই অন্য কোনো পেজে চলে যাবে, তখনই unload ইভেন্টটি ফায়ার হবে, যা এখন আর সত্য নয় (এবং অনেক দিন ধরেই সত্য নয় )।

ফলে ব্রাউজারগুলো একটি উভয়সঙ্কটের সম্মুখীন হয়; তাদের এমন কিছুর মধ্যে একটি বেছে নিতে হয় যা ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে পারে—কিন্তু একই সাথে পেজটি ভেঙে যাওয়ার ঝুঁকিও তৈরি করতে পারে।

ডেস্কটপে, ক্রোম এবং ফায়ারফক্স এমন পেজগুলোকে bfcache-এর জন্য অযোগ্য করে তুলেছে যেগুলোতে একটি unload লিসেনার যুক্ত করা হয়। এটি তুলনামূলকভাবে কম ঝুঁকিপূর্ণ হলেও এর ফলে অনেক পেজই বাদ পড়ে যায়। সাফারি unload ইভেন্ট লিসেনারসহ কিছু পেজ ক্যাশ করার চেষ্টা করে, কিন্তু সম্ভাব্য সমস্যা এড়াতে ব্যবহারকারী অন্য পেজে চলে গেলে এটি unload ইভেন্টটি চালায় না, যা এই ইভেন্টটিকে খুবই অনির্ভরযোগ্য করে তোলে।

মোবাইলে, Chrome এবং Safari সেইসব পেজ ক্যাশ করার চেষ্টা করে যেগুলিতে একটি unload ইভেন্ট লিসেনার থাকে, কারণ এতে পেজ ভেঙে যাওয়ার ঝুঁকি কম থাকে। এর কারণ হলো, মোবাইলে unload ইভেন্টটি বরাবরই অত্যন্ত অনির্ভরযোগ্য। Firefox, unload ব্যবহারকারী পেজগুলিকে bfcache-এর জন্য অযোগ্য বলে মনে করে, তবে iOS এর ক্ষেত্রে এটি প্রযোজ্য নয়, যেখানে সমস্ত ব্রাউজার WebKit রেন্ডারিং ইঞ্জিন ব্যবহার করে এবং তাই Safari-এর মতো আচরণ করে।

unload ইভেন্টের পরিবর্তে pagehide ইভেন্ট ব্যবহার করুন। unload ইভেন্ট যেখানেই ফায়ার হয়, pagehide ইভেন্টও সেখানেই ফায়ার হয় এবং কোনো পেজ বিএফক্যাশে (bfcache) রাখা হলেও এটি ফায়ার হয়।

প্রকৃতপক্ষে, লাইটহাউসের একটি no-unload-listeners অডিট রয়েছে, যা ডেভেলপারদের সতর্ক করে দেবে যদি তাদের পেজের কোনো জাভাস্ক্রিপ্ট (তৃতীয় পক্ষের লাইব্রেরির কোড সহ) একটি unload ইভেন্ট লিসেনার যোগ করে।

এর অবিশ্বস্ততা এবং bfcache-এর পারফরম্যান্সের উপর প্রভাবের কারণে, Chrome unload ইভেন্টটি বাতিল করার কথা ভাবছে।

একটি পৃষ্ঠায় আনলোড হ্যান্ডলার ব্যবহার প্রতিরোধ করতে অনুমতি নীতি ব্যবহার করুন।

যেসব সাইট unload ইভেন্ট হ্যান্ডলার ব্যবহার করে না, তারা একটি পারমিশন পলিসি ব্যবহারের মাধ্যমে নিশ্চিত করতে পারে যে এগুলি যুক্ত না হয়।

Permissions-Policy: unload=()

এটি তৃতীয় পক্ষ বা এক্সটেনশনগুলিকে আনলোড হ্যান্ডলার যোগ করে সাইটের গতি কমিয়ে দেওয়া এবং সাইটটিকে বিএফক্যাশের (bfcache) জন্য অযোগ্য করে তোলা থেকেও বিরত রাখে।

শুধুমাত্র শর্তসাপেক্ষে beforeunload লিসেনার যোগ করুন।

beforeunload ইভেন্টটি আধুনিক ব্রাউজারগুলোর bfcache-এ আপনার পেজগুলোকে অযোগ্য করে তুলবে না, কিন্তু আগে এটি করত এবং এটি এখনও নির্ভরযোগ্য নয়, তাই একান্ত প্রয়োজন না হলে এটি ব্যবহার করা থেকে বিরত থাকুন।

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

না
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
এই কোডটি শর্তহীনভাবে একটি beforeunload লিসেনার যোগ করে।
করুন
function beforeUnloadListener(event) {
  event.preventDefault();
  return event.returnValue = 'Are you sure you want to exit?';
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  window.addEventListener('beforeunload', beforeUnloadListener);
});

// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
  window.removeEventListener('beforeunload', beforeUnloadListener);
});
এই কোডটি শুধুমাত্র প্রয়োজনের সময়ই beforeunload লিসেনারটি যোগ করে (এবং অপ্রয়োজনে তা সরিয়ে দেয়)।

Cache-Control: no-store এর ব্যবহার কমান।

Cache-Control: no-store হলো একটি HTTP হেডার যা ওয়েব সার্ভারগুলো রেসপন্সের উপর সেট করতে পারে এবং এটি ব্রাউজারকে কোনো HTTP ক্যাশে রেসপন্সটি সংরক্ষণ না করার নির্দেশ দেয়। এটি সংবেদনশীল ব্যবহারকারীর তথ্য ধারণকারী রিসোর্সগুলোর জন্য ব্যবহৃত হয়, যেমন লগইনের মাধ্যমে যাচাই করা হয় এমন পেজ।

যদিও bfcache কোনো HTTP ক্যাশ নয়, ঐতিহাসিকভাবে, যখন কোনো সাবরিসোর্সের পরিবর্তে সরাসরি পেজ রিসোর্সে Cache-Control: no-store সেট করা হয়, তখন ব্রাউজারগুলো পেজটিকে bfcache-এ সংরক্ষণ করে না। ফলে Cache-Control: no-store ব্যবহারকারী পেজগুলো bfcache-এর জন্য যোগ্য নাও হতে পারে। গোপনীয়তা রক্ষার কথা মাথায় রেখে Chrome-এর জন্য এই আচরণটি পরিবর্তন করার কাজ চলছে

যেহেতু Cache-Control: no-store একটি পেজের bfcache-এর জন্য যোগ্যতাকে সীমাবদ্ধ করে, তাই এটি শুধুমাত্র সেইসব পেজে সেট করা উচিত যেগুলিতে সংবেদনশীল তথ্য থাকে এবং যেখানে কোনো ধরনের ক্যাশিং কখনোই উপযুক্ত নয়।

যেসব পেজের জন্য সবসময় হালনাগাদ কন্টেন্ট পরিবেশন করা প্রয়োজন—এবং সেই কন্টেন্টে কোনো সংবেদনশীল তথ্য থাকে না— Cache-Control: no-cache অথবা Cache-Control: max-age=0 ব্যবহার করুন। এই নির্দেশিকাগুলো ব্রাউজারকে কন্টেন্ট পরিবেশন করার আগে তা পুনরায় যাচাই করতে নির্দেশ দেয় এবং এগুলো কোনো পেজের bfcache যোগ্যতাকে প্রভাবিত করে না।

উল্লেখ্য যে, যখন কোনো পৃষ্ঠা bfcache থেকে পুনরুদ্ধার করা হয়, তখন তা HTTP ক্যাশ থেকে নয়, বরং মেমরি থেকে পুনরুদ্ধার করা হয়। ফলে, Cache-Control: no-cache বা Cache-Control: max-age=0 এর মতো নির্দেশাবলী বিবেচনায় নেওয়া হয় না এবং ব্যবহারকারীর কাছে বিষয়বস্তু প্রদর্শিত হওয়ার আগে কোনো পুনঃযাচাইকরণ ঘটে না।

তবে, এটি সম্ভবত ব্যবহারকারীর জন্য আরও ভালো অভিজ্ঞতা দেবে, কারণ বিএফক্যাশ (bfcache) রিস্টোর তাৎক্ষণিক হয় এবং—যেহেতু পেজগুলো বিএফক্যাশে বেশিক্ষণ থাকে না—তাই কন্টেন্ট পুরোনো হয়ে যাওয়ার সম্ভাবনা কম। কিন্তু, যদি আপনার কন্টেন্ট প্রতি মিনিটে পরিবর্তিত হয়, তাহলে আপনি পরবর্তী বিভাগে বর্ণিত পদ্ধতি অনুযায়ী pageshow ইভেন্ট ব্যবহার করে যেকোনো আপডেট ফেচ (fetch) করতে পারেন।

bfcache রিস্টোর করার পর পুরোনো বা সংবেদনশীল ডেটা আপডেট করুন।

আপনার সাইট যদি ব্যবহারকারীর অবস্থা—বিশেষ করে কোনো সংবেদনশীল তথ্য—সংরক্ষণ করে, তাহলে bfcache থেকে কোনো পৃষ্ঠা পুনরুদ্ধার করার পর সেই ডেটা আপডেট বা মুছে ফেলা প্রয়োজন।

উদাহরণস্বরূপ, যদি কোনো ব্যবহারকারী একটি চেকআউট পৃষ্ঠায় যান এবং তারপরে তার শপিং কার্ট আপডেট করেন, তাহলে bfcache থেকে একটি পুরোনো পৃষ্ঠা পুনরুদ্ধার করা হলে ব্যাক নেভিগেশনের ফলে সম্ভাব্যভাবে পুরোনো তথ্য প্রকাশ হয়ে যেতে পারে।

আরেকটি, আরও গুরুতর উদাহরণ হলো, যদি কোনো ব্যবহারকারী একটি পাবলিক কম্পিউটার থেকে কোনো সাইট থেকে সাইন আউট করেন এবং পরবর্তী ব্যবহারকারী ব্যাক বাটনে ক্লিক করেন। এর ফলে এমন ব্যক্তিগত তথ্য ফাঁস হয়ে যেতে পারে, যা ব্যবহারকারী লগ আউট করার সময় মুছে গেছে বলে ধরে নিয়েছিলেন।

এই ধরনের পরিস্থিতি এড়ানোর জন্য, যদি event.persisted true হয়, তাহলে pageshow ইভেন্টের পরে পেজটি সবসময় আপডেট করা ভালো।

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Do any checks and updates to the page
  }
});

আদর্শগতভাবে কন্টেন্টটি সরাসরি আপডেট করা উচিত হলেও, কিছু পরিবর্তনের জন্য আপনি সম্পূর্ণ রিলোড করতে চাইতে পারেন। নিম্নলিখিত কোডটি pageshow ইভেন্টে একটি সাইট-নির্দিষ্ট কুকির উপস্থিতি পরীক্ষা করে এবং কুকিটি খুঁজে না পেলে রিলোড করে:

window.addEventListener('pageshow', (event) => {
  if (event.persisted && !document.cookie.match(/my-cookie)) {
    // Force a reload if the user has logged out.
    location.reload();
  }
});

রিলোড করার সুবিধা হলো এটি হিস্ট্রি সংরক্ষণ করে রাখে (যাতে সামনে নেভিগেট করা যায়), কিন্তু কিছু ক্ষেত্রে রিডাইরেক্ট করা বেশি উপযুক্ত হতে পারে।

Ads এবং bfcache পুনরুদ্ধার

প্রতিবার সামনে বা পেছনে যাওয়ার সময় নতুন করে বিজ্ঞাপন দেখানোর জন্য বিএফক্যাশ (bfcache) ব্যবহার এড়িয়ে চলার একটি প্রবণতা থাকতে পারে। তবে, এটি যেমন পারফরম্যান্সের ওপর প্রভাব ফেলে, তেমনই এই ধরনের আচরণ বিজ্ঞাপনের প্রতি ব্যবহারকারীর সম্পৃক্ততা বাড়ায় কিনা, তা নিয়েও প্রশ্ন রয়েছে। ব্যবহারকারীরা হয়তো এমন কোনো বিজ্ঞাপন দেখেছেন যেটিতে ফিরে এসে ক্লিক করতে চেয়েছিলেন, কিন্তু বিএফক্যাশ থেকে পুনরুদ্ধার না করে শুধু রিলোড করার ফলে তারা তা করতে পারেননি। কোনো কিছু অনুমান করার আগে এই পরিস্থিতিটি পরীক্ষা করা—বিশেষত একটি এ/বি টেস্টের মাধ্যমে—গুরুত্বপূর্ণ।

যেসব সাইট bfcache রিস্টোরের সময় বিজ্ঞাপন রিফ্রেশ করতে চায়, তাদের জন্য event.persisted true থাকা অবস্থায় pageshow ইভেন্টে শুধু বিজ্ঞাপনগুলো রিফ্রেশ করলে পেজের পারফরম্যান্সে কোনো প্রভাব না ফেলেই এটি করা সম্ভব হয়। আপনার বিজ্ঞাপন প্রদানকারীর সাথে বিষয়টি যাচাই করে নিন, তবে গুগল পাবলিশিং ট্যাগ ব্যবহার করে এটি কীভাবে করতে হয় তার একটি উদাহরণ এখানে দেওয়া হলো

window.opener উল্লেখ এড়িয়ে চলুন।

পুরানো ব্রাউজারগুলিতে, যদি rel="noopener" উল্লেখ না করে target=_blank সহ কোনো লিঙ্ক থেকে window.open() ব্যবহার করে একটি পৃষ্ঠা খোলা হতো, তাহলে যে পৃষ্ঠাটি খুলত তাতে খোলা পৃষ্ঠাটির window অবজেক্টের একটি রেফারেন্স থাকত।

নিরাপত্তাজনিত ঝুঁকি হওয়ার পাশাপাশি, যে পেজে window.opener রেফারেন্সটি নাল (null) নয়, সেটিকে নিরাপদে bfcache-এ রাখা যায় না, কারণ এর ফলে সেটিকে অ্যাক্সেস করতে চাওয়া যেকোনো পেজ অকার্যকর হয়ে যেতে পারে।

ফলস্বরূপ, window.opener রেফারেন্স তৈরি করা এড়িয়ে চলাই ভালো। যখনই সম্ভব rel="noopener" ব্যবহার করে আপনি এটি করতে পারেন (উল্লেখ্য, এটি এখন সমস্ত আধুনিক ব্রাউজারে ডিফল্ট)। যদি আপনার সাইটে একটি উইন্ডো খোলার এবং window.postMessage() এর মাধ্যমে এটিকে নিয়ন্ত্রণ করার অথবা সরাসরি window অবজেক্টকে রেফারেন্স করার প্রয়োজন হয়, তাহলে খোলা উইন্ডো বা ওপেনার কোনোটিই bfcache-এর জন্য উপযুক্ত হবে না।

ব্যবহারকারী অন্যত্র চলে যাওয়ার আগে খোলা সংযোগগুলি বন্ধ করুন।

পূর্বে যেমন উল্লেখ করা হয়েছে, যখন কোনো পেজ bfcache-এ রাখা হয়, তখন এটি সমস্ত নির্ধারিত জাভাস্ক্রিপ্ট টাস্ক থামিয়ে দেয় এবং পেজটি ক্যাশ থেকে বের করে নিলে সেগুলোকে পুনরায় চালু করে।

যদি এই নির্ধারিত জাভাস্ক্রিপ্ট টাস্কগুলো শুধুমাত্র DOM API—অথবা শুধু বর্তমান পৃষ্ঠার জন্য সীমাবদ্ধ অন্যান্য API—অ্যাক্সেস করে, তাহলে ব্যবহারকারীর কাছে পৃষ্ঠাটি অদৃশ্য থাকাকালীন এই টাস্কগুলো পজ করে রাখলে কোনো সমস্যা হবে না।

তবে, যদি এই টাস্কগুলো এমন API-এর সাথে সংযুক্ত থাকে যা একই অরিজিনের অন্যান্য পেজ থেকেও অ্যাক্সেসযোগ্য (যেমন: IndexedDB, Web Locks, WebSockets), তাহলে এটি সমস্যাজনক হতে পারে, কারণ এই টাস্কগুলো পজ করলে অন্যান্য ট্যাবের কোড চালানো বন্ধ হয়ে যেতে পারে।

ফলস্বরূপ, কিছু ব্রাউজার নিম্নলিখিত পরিস্থিতিগুলিতে কোনো পৃষ্ঠাকে bfcache-এ রাখার চেষ্টা করবে না:

  • যেসব পেজে একটি খোলা IndexedDB সংযোগ রয়েছে।
  • যেসব পেজে এখনও fetch() বা XMLHttpRequest চালু আছে।
  • যেসব পেজে খোলা WebSocket বা WebRTC সংযোগ রয়েছে। Chrome (১৪৯ সংস্করণ অনুযায়ী) এবং Safari খোলা WebSocket ব্লক করে না, কিন্তু অন্যান্য ব্রাউজার তা করে।

আপনার পেজ যদি এই API-গুলোর কোনোটি ব্যবহার করে থাকে, তাহলে আমরা pagehide বা freeze ইভেন্টের সময় কানেকশন বন্ধ করতে এবং অবজারভারদের রিমুভ বা ডিসকানেক্ট করার জন্য দৃঢ়ভাবে সুপারিশ করছি। এর ফলে ব্রাউজার অন্য খোলা ট্যাবগুলোকে প্রভাবিত করার ঝুঁকি ছাড়াই নিরাপদে পেজটি ক্যাশ করতে পারে।

এরপর, যদি পেজটি bfcache থেকে পুনরুদ্ধার করা হয়, তাহলে আপনি pageshow বা resume ইভেন্টের সময় সেই API-গুলো পুনরায় খুলতে বা সেগুলোতে পুনরায় সংযোগ করতে পারেন, অথবা error বা close ইভেন্ট ব্যবহার করে সেগুলোকে সবসময় স্বয়ংক্রিয়ভাবে পুনরায় খোলার ব্যবস্থা করতে পারেন। একাধিক ইভেন্ট ব্যবহার করলে, খেয়াল রাখবেন যেন একাধিক সংযোগ খোলা না হয়।

নিম্নলিখিত উদাহরণটি দেখায় যে কীভাবে pagehide ইভেন্ট লিসেনারে একটি খোলা সংযোগ বন্ধ করার মাধ্যমে IndexedDB ব্যবহারকারী পেজগুলি bfcache-এর জন্য যোগ্য কিনা তা নিশ্চিত করা যায়:

let dbPromise;
function openDB() {
  if (!dbPromise) {
    dbPromise = new Promise((resolve, reject) => {
      const req = indexedDB.open('my-db', 1);
      req.onupgradeneeded = () => req.result.createObjectStore('keyval');
      req.onerror = () => reject(req.error);
      req.onsuccess = () => resolve(req.result);
    });
  }
  return dbPromise;
}

// Close the connection to the database when the user leaves.
window.addEventListener('pagehide', () => {
  if (dbPromise) {
    dbPromise.then(db => db.close());
    dbPromise = null;
  }
});

// Open the connection when the page is loaded or restored from bfcache.
window.addEventListener('pageshow', () => openDB());

আপনার পেজগুলো ক্যাশেযোগ্য কিনা তা পরীক্ষা করুন।

আপনার পেজগুলো bfcache-এর জন্য অপ্টিমাইজ করা আছে কিনা তা পরীক্ষা করতে এবং সেগুলোর যোগ্যতা অর্জনে বাধা সৃষ্টিকারী যেকোনো সমস্যা শনাক্ত করতে Chrome DevTools আপনাকে সাহায্য করতে পারে।

একটি পৃষ্ঠা পরীক্ষা করতে:

  1. ক্রোমে পৃষ্ঠাটিতে যান।
  2. DevTools-এ, Application -> Back-forward Cache- এ যান।
  3. রান টেস্ট বাটনটিতে ক্লিক করুন। এরপর ডেভটুলস পেজটি বিএফক্যাশ (bfcache) থেকে পুনরুদ্ধার করা যাবে কিনা তা নির্ধারণ করার জন্য অন্য পেজে গিয়ে আবার ফিরে আসার চেষ্টা করে।
DevTools-এ ব্যাক-ফরোয়ার্ড ক্যাশে প্যানেল
DevTools-এর ব্যাক-ফরোয়ার্ড ক্যাশে প্যানেল।

পরীক্ষাটি সফল হলে, প্যানেলটি "ব্যাক-ফরোয়ার্ড ক্যাশে থেকে পুনরুদ্ধার করা হয়েছে" বার্তাটি প্রদর্শন করে।

DevTools জানাচ্ছে যে bfcache থেকে একটি পৃষ্ঠা সফলভাবে পুনরুদ্ধার করা হয়েছে।
পৃষ্ঠাটি সফলভাবে পুনরুদ্ধার করা হয়েছে।

যদি এটি অসফল হয়, প্যানেলটি তার কারণ নির্দেশ করে। যদি কারণটি এমন হয় যা আপনি একজন ডেভেলপার হিসেবে সমাধান করতে পারেন, তবে প্যানেলটি সেটিকে করণীয় (Actionable) হিসেবে চিহ্নিত করে।

DevTools bfcache থেকে একটি পৃষ্ঠা পুনরুদ্ধার করতে ব্যর্থতার কথা জানাচ্ছে।
একটি কার্যকর ফলাফলসহ bfcache টেস্টটি ব্যর্থ হয়েছে।

এই উদাহরণে, unload ইভেন্ট লিসেনার ব্যবহারের ফলে পেজটি বিএফক্যাশের জন্য অযোগ্য হয়ে পড়ে। আপনি unload পরিবর্তে pagehide ব্যবহার করে এটি ঠিক করতে পারেন।

করুন
window.addEventListener('pagehide', ...);
না
window.addEventListener('unload', ...);

Lighthouse 10.0-এ একটি bfcache অডিটও যোগ করা হয়েছে , যা একই ধরনের পরীক্ষা করে। আরও তথ্যের জন্য, bfcache অডিটের ডক্স দেখুন।

bfcache কীভাবে অ্যানালিটিক্স এবং পারফরম্যান্স পরিমাপকে প্রভাবিত করে

আপনি যদি আপনার সাইটের ভিজিট পরিমাপ করতে কোনো অ্যানালিটিক্স টুল ব্যবহার করেন, তাহলে আপনি হয়তো লক্ষ্য করবেন যে, ক্রোম আরও বেশি ব্যবহারকারীর জন্য বিএফক্যাশ (bfcache) চালু করার ফলে রিপোর্ট করা মোট পেজভিউয়ের সংখ্যা কমে গেছে।

প্রকৃতপক্ষে, আপনি সম্ভবত ইতিমধ্যেই bfcache ব্যবহারকারী অন্যান্য ব্রাউজারগুলো থেকে পেজভিউ কম দেখাচ্ছেন, কারণ অনেক জনপ্রিয় অ্যানালিটিক্স লাইব্রেরি bfcache রিস্টোরকে নতুন পেজভিউ হিসেবে গণনা করে না।

আপনার পেজভিউ গণনায় বিএফক্যাশ রিস্টোর অন্তর্ভুক্ত করতে, pageshow ইভেন্টের জন্য লিসেনার সেট করুন এবং persisted প্রপার্টিটি চেক করুন।

নিম্নলিখিত উদাহরণটি দেখায় কিভাবে গুগল অ্যানালিটিক্স দিয়ে এটি করতে হয়। অন্যান্য অ্যানালিটিক্স টুলগুলোও সম্ভবত একই ধরনের যুক্তি ব্যবহার করে:

// Send a pageview when the page is first loaded.
// This happens by default just by loading gtag
gtag('config', 'TAG_ID');

window.addEventListener('pageshow', (event) => {
  // Send another pageview if the page is restored from bfcache.
  if (event.persisted) {
    gtag('event', 'page_view');
  }
});

আপনার bfcache হিট অনুপাত পরিমাপ করুন

আপনি bfcache ব্যবহৃত হয়েছে কিনা তাও পরিমাপ করতে চাইতে পারেন, যা bfcache ব্যবহার করছে না এমন পৃষ্ঠাগুলি শনাক্ত করতে সাহায্য করবে। পৃষ্ঠা লোডের জন্য নেভিগেশন টাইপ পরিমাপ করার মাধ্যমে এটি করা যেতে পারে:

// Send a navigation_type when the page is first loaded.
// To do this disable the default pageview so you can manually send it
// supplemented with the additional detail.
gtag('config', 'TAG_ID', { send_page_view: false });
gtag('event', 'page_view', {
   'navigation_type': performance.getEntriesByType('navigation')[0].type;
});

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Send another pageview if the page is restored from bfcache.
    gtag('event', 'page_view', {
      'navigation_type': 'back_forward_cache';
    });
  }
});

back_forward নেভিগেশন এবং back_forward_cache নেভিগেশনের সংখ্যা ব্যবহার করে আপনার bfcache হিট রেশিও গণনা করুন।

এটা উপলব্ধি করা গুরুত্বপূর্ণ যে, সাইট মালিকের নিয়ন্ত্রণের বাইরে এমন বেশ কিছু পরিস্থিতি রয়েছে, যখন ব্যাক/ফরোয়ার্ড নেভিগেশন bfcache ব্যবহার করে না, যার মধ্যে রয়েছে:

  • যখন ব্যবহারকারী ব্রাউজারটি বন্ধ করে আবার চালু করে
  • যখন ব্যবহারকারী একটি ট্যাব নকল করে
  • যখন ব্যবহারকারী একটি ট্যাব বন্ধ করে আবার খোলে

এইসব ক্ষেত্রের কয়েকটিতে কিছু ব্রাউজার মূল নেভিগেশন টাইপটি সংরক্ষণ করতে পারে এবং তাই এগুলি ব্যাক/ফরোয়ার্ড নেভিগেশন না হওয়া সত্ত্বেও back_forward টাইপের নেভিগেশন দেখাতে পারে।

ওই বর্জনগুলো ছাড়াও মেমরি সংরক্ষণের জন্য একটি নির্দিষ্ট সময় পর বিএফক্যাশ (bfcache) বাতিল করে দেওয়া হবে।

সুতরাং, ওয়েবসাইট মালিকদের সমস্ত back_forward নেভিগেশনের জন্য ১০০% বিএফক্যাশ হিট রেশিও আশা করা উচিত নয়। তবে, এই রেশিও পরিমাপ করা এমন পেজ শনাক্ত করতে সহায়ক হতে পারে, যেখানে পেজটি নিজেই ব্যাক ও ফরওয়ার্ড নেভিগেশনের একটি বড় অংশের জন্য বিএফক্যাশ ব্যবহারে বাধা দিচ্ছে।

পেজগুলো কেন bfcache ব্যবহার করে না, তার কারণগুলো জানতে Chrome টিম NotRestoredReasons API যুক্ত করেছে, যাতে ডেভেলপাররা তাদের bfcache হিট রেট উন্নত করতে পারেন। Chrome টিম CrUX-এ নেভিগেশন টাইপও যুক্ত করেছে, যার ফলে নিজে পরিমাপ না করেও bfcache নেভিগেশনের সংখ্যা দেখা সম্ভব হয়েছে।

কর্মক্ষমতা পরিমাপ

bfcache ফিল্ড থেকে সংগৃহীত পারফরম্যান্স মেট্রিকগুলোকেও নেতিবাচকভাবে প্রভাবিত করতে পারে, বিশেষ করে সেইসব মেট্রিক যা পেজ লোড হওয়ার সময় পরিমাপ করে।

যেহেতু bfcache নেভিগেশন একটি নতুন পেজ লোড শুরু করার পরিবর্তে একটি বিদ্যমান পেজ পুনরুদ্ধার করে, তাই bfcache সক্রিয় থাকলে সংগৃহীত মোট পেজ লোডের সংখ্যা কমে যাবে। তবে, গুরুত্বপূর্ণ বিষয় হলো, bfcache পুনরুদ্ধারের মাধ্যমে প্রতিস্থাপিত পেজ লোডগুলো সম্ভবত আপনার ডেটাসেটের সবচেয়ে দ্রুততম পেজ লোডগুলোর মধ্যে কয়েকটি ছিল। এর কারণ হলো, ব্যাক এবং ফরোয়ার্ড নেভিগেশনগুলো সংজ্ঞানুসারে পুনরাবৃত্তিমূলক ভিজিট, এবং পুনরাবৃত্তিমূলক পেজ লোডগুলো সাধারণত প্রথমবারের ভিজিটরদের পেজ লোডের চেয়ে দ্রুততর হয় (যেমনটি আগে উল্লেখ করা হয়েছে, HTTP ক্যাশিংয়ের কারণে)।

এর ফলে আপনার ডেটাসেটে দ্রুত পেজ লোডের সংখ্যা কমে যায়, যা সম্ভবত ডেটার বিন্যাসকে আরও ধীর করে দেবে—যদিও ব্যবহারকারীর অভিজ্ঞতায় পারফরম্যান্স সম্ভবত উন্নত হয়েছে!

এই সমস্যাটি মোকাবেলা করার কয়েকটি উপায় আছে। একটি হলো সমস্ত পেজ লোড মেট্রিককে তাদের নিজ নিজ ন্যাভিগেশন টাইপ —যেমন: navigate , reload , back_forward , বা prerender দিয়ে টীকাযুক্ত করা। এর ফলে, সামগ্রিক বিন্যাস নেতিবাচক দিকে ঝুঁকে থাকলেও, আপনি এই ন্যাভিগেশন টাইপগুলোর মধ্যে আপনার পারফরম্যান্স নিরীক্ষণ চালিয়ে যেতে পারবেন। আমরা Time to First Byte (TTFB)- এর মতো ব্যবহারকারী-কেন্দ্রিক নয় এমন পেজ লোড মেট্রিকগুলোর জন্য এই পদ্ধতিটি সুপারিশ করি।

কোর ওয়েব ভাইটালস- এর মতো ব্যবহারকারী-কেন্দ্রিক মেট্রিকগুলোর ক্ষেত্রে, এমন একটি মান রিপোর্ট করা আরও ভালো বিকল্প যা ব্যবহারকারীর অভিজ্ঞতাকে আরও নির্ভুলভাবে উপস্থাপন করে।

কোর ওয়েব ভাইটালসের উপর প্রভাব

কোর ওয়েব ভাইটালস একটি ওয়েব পেজের ব্যবহারকারীর অভিজ্ঞতাকে বিভিন্ন দিক (যেমন লোডিং স্পিড, ইন্টারঅ্যাকটিভিটি, ভিজ্যুয়াল স্ট্যাবিলিটি) জুড়ে পরিমাপ করে। যেহেতু ব্যবহারকারীরা সম্পূর্ণ পেজ লোড হওয়ার চেয়ে বিএফক্যাশ রিস্টোরকে দ্রুততর নেভিগেশন হিসেবে অনুভব করেন, তাই কোর ওয়েব ভাইটালস মেট্রিক্সে এর প্রতিফলন থাকাটা জরুরি। সর্বোপরি, বিএফক্যাশ চালু ছিল কি না, তা নিয়ে একজন ব্যবহারকারীর কোনো মাথাব্যথা নেই; তাদের কাছে শুধু এটাই গুরুত্বপূর্ণ যে নেভিগেশনটি দ্রুত ছিল!

যেসব টুল কোর ওয়েব ভাইটালস মেট্রিকস সংগ্রহ ও রিপোর্ট করে, যেমন ক্রোম ইউজার এক্সপেরিয়েন্স রিপোর্ট , সেগুলো তাদের ডেটাসেটে বিএফক্যাশ রিস্টোরকে আলাদা পেজ ভিজিট হিসেবে গণ্য করে। এবং যদিও বিএফক্যাশ রিস্টোরের পরে এই মেট্রিকসগুলো পরিমাপ করার জন্য কোনো ডেডিকেটেড ওয়েব পারফরম্যান্স এপিআই নেই, আপনি বিদ্যমান ওয়েব এপিআই ব্যবহার করে এগুলোর আনুমানিক মান বের করতে পারেন:

  • লার্জেস্ট কন্টেন্টফুল পেইন্ট (LCP)- এর জন্য, pageshow ইভেন্টের টাইমস্ট্যাম্প এবং পরবর্তী পেইন্ট করা ফ্রেমের টাইমস্ট্যাম্পের মধ্যকার ডেল্টা ব্যবহার করুন, কারণ ফ্রেমের সমস্ত এলিমেন্ট একই সময়ে পেইন্ট করা হবে। বিএফক্যাশ রিস্টোরের ক্ষেত্রে, LCP এবং FCP একই হয়।
  • পরবর্তী পেইন্টে ইন্টারঅ্যাকশনের (INP) জন্য, আপনার বিদ্যমান পারফরম্যান্স অবজারভারটি ব্যবহার করতে থাকুন, কিন্তু বর্তমান INP মানটি 0-তে রিসেট করুন।
  • কিউমুলেটিভ লেআউট শিফট (CLS)- এর জন্য, আপনার বিদ্যমান পারফরম্যান্স অবজারভার ব্যবহার করতে থাকুন, কিন্তু বর্তমান CLS মানটি 0-তে রিসেট করুন।

bfcache প্রতিটি মেট্রিককে কীভাবে প্রভাবিত করে সে সম্পর্কে আরও বিশদ জানতে, স্বতন্ত্র Core Web Vitals মেট্রিক গাইড পৃষ্ঠাগুলি দেখুন। এই মেট্রিকগুলির bfcache সংস্করণগুলি কীভাবে প্রয়োগ করতে হয় তার একটি নির্দিষ্ট উদাহরণের জন্য, web-vitals JS লাইব্রেরিতে সেগুলি যুক্ত করা PR-টি দেখুন।

web-vitals জাভাস্ক্রিপ্ট লাইব্রেরি তার রিপোর্ট করা মেট্রিক্সে bfcache রিস্টোর সমর্থন করে

অতিরিক্ত সম্পদ

,

প্রকাশিত: ২৫ মে, ২০২৩, সর্বশেষ হালনাগাদ: ২ জুলাই, ২০২৬

ব্যাক/ফরোয়ার্ড ক্যাশে (বা বিএফক্যাশ) হলো একটি ব্রাউজার অপটিমাইজেশন যা তাৎক্ষণিক সামনে ও পেছনে যাওয়ার সুবিধা দেয়। এটি ব্রাউজিং অভিজ্ঞতাকে উল্লেখযোগ্যভাবে উন্নত করে, বিশেষ করে ধীরগতির নেটওয়ার্ক বা ডিভাইস ব্যবহারকারীদের জন্য।

ওয়েব ডেভেলপার হিসেবে, bfcache-এর জন্য আপনার পেজগুলোকে কীভাবে অপ্টিমাইজ করতে হয় তা বোঝা অত্যন্ত জরুরি, যাতে আপনার ব্যবহারকারীরা এর সুবিধাগুলো ভোগ করতে পারেন।

ব্রাউজার সামঞ্জস্যতা

ক্রোম ৯৬ সংস্করণ থেকে, ফায়ারফক্স এবং সাফারি সহ সকল প্রধান ব্রাউজারে একটি bfcache অন্তর্ভুক্ত থাকে।

বিএফক্যাশের মৌলিক বিষয়াবলী

ব্যাক/ফরোয়ার্ড ক্যাশে (bfcache) ব্যবহার করলে, ব্যবহারকারী অন্য পেজে চলে গেলে পেজটি মুছে ফেলার পরিবর্তে, আমরা সেই মুছে ফেলার প্রক্রিয়াটি স্থগিত রাখি এবং জাভাস্ক্রিপ্ট (JS) চালানো থামিয়ে দিই। যদি ব্যবহারকারী শীঘ্রই ফিরে আসেন, আমরা পেজটিকে আবার দৃশ্যমান করে তুলি এবং জাভাস্ক্রিপ্ট চালানো পুনরায় চালু করি। এর ফলে ব্যবহারকারী প্রায় সঙ্গে সঙ্গেই পেজে ফিরে যেতে পারেন।

কতবার এমন হয়েছে যে আপনি কোনো ওয়েবসাইটে গিয়ে অন্য পেজে যাওয়ার জন্য লিঙ্কে ক্লিক করেছেন, কিন্তু পরে বুঝতে পেরেছেন যে এটি আপনার কাঙ্ক্ষিত পেজ নয় এবং ব্যাক বাটনে ক্লিক করেছেন? সেই মুহূর্তে, আগের পেজটি কত দ্রুত লোড হবে, তাতে bfcache একটি বড় পার্থক্য গড়ে দিতে পারে।

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

নেভিগেশনে bfcache কতটা গতি বাড়াতে পারে তা বুঝতে এর কার্যকারিতার এই ভিডিওটি দেখুন:

bfcache ব্যবহার করলে সামনে ও পেছনে যাওয়ার সময় পেজগুলো অনেক দ্রুত লোড হয়।

ভিডিওটিতে, bfcache সহ উদাহরণটি এটি ছাড়া উদাহরণটির চেয়ে বেশ খানিকটা দ্রুততর।

bfcache শুধু নেভিগেশনের গতিই বাড়ায় না, এটি ডেটা ব্যবহারও কমায়, কারণ রিসোর্সগুলো পুনরায় ডাউনলোড করার প্রয়োজন হয় না।

ক্রোম ব্যবহারের ডেটা থেকে দেখা যায় যে, ডেস্কটপে প্রতি ১০টি নেভিগেশনের মধ্যে ১টি এবং মোবাইলে প্রতি ৫টি নেভিগেশনের মধ্যে ১টি হয় পেছনে যাওয়া অথবা সামনে যাওয়া। bfcache সক্রিয় থাকলে, ব্রাউজারগুলো প্রতিদিন শত শত কোটি ওয়েব পেজের জন্য প্রয়োজনীয় ডেটা ট্রান্সফার এবং লোড হওয়ার সময়কে সম্পূর্ণরূপে দূর করতে পারে!

"ক্যাশ" কীভাবে কাজ করে

bfcache যে "ক্যাশ" ব্যবহার করে তা HTTP ক্যাশ থেকে ভিন্ন, যা বারবার নেভিগেশনের গতি বাড়াতে নিজস্ব ভূমিকা পালন করে। bfcache হলো জাভাস্ক্রিপ্ট হিপ সহ মেমরিতে থাকা সম্পূর্ণ পেজটির একটি স্ন্যাপশট, যেখানে HTTP ক্যাশে শুধুমাত্র পূর্বে করা অনুরোধগুলোর প্রতিক্রিয়া থাকে। যেহেতু একটি পেজ লোড করার জন্য প্রয়োজনীয় সমস্ত অনুরোধ HTTP ক্যাশ থেকে পূরণ হওয়া খুবই বিরল, তাই bfcache রিস্টোর ব্যবহার করে বারবার ভিজিট করা এমনকি সবচেয়ে ভালোভাবে অপ্টিমাইজ করা নন-bfcache নেভিগেশনের চেয়েও সর্বদা দ্রুততর হয়।

পরবর্তীতে আবার চালু করার উদ্দেশ্যে কোনো পেজকে ফ্রিজ করার ক্ষেত্রে, চলমান কোড কীভাবে সবচেয়ে ভালোভাবে সংরক্ষণ করা যায়, সেই বিষয়ে কিছু জটিলতা রয়েছে। উদাহরণস্বরূপ, পেজটি bfcache-এ থাকা অবস্থায় টাইমআউট শেষ হয়ে গেলে setTimeout() কলগুলো আপনি কীভাবে সামলাবেন?

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

কিছু ক্ষেত্রে, যেমন টাইমআউট এবং প্রমিজের জন্য, এটি বেশ কম ঝুঁকিপূর্ণ, কিন্তু অন্যান্য ক্ষেত্রে এটি বিভ্রান্তিকর বা অপ্রত্যাশিত আচরণের কারণ হতে পারে। উদাহরণস্বরূপ, যদি ব্রাউজার এমন কোনো কাজ থামিয়ে দেয় যা একটি IndexedDB ট্রানজ্যাকশনের অংশ হিসেবে প্রয়োজন, তবে এটি একই অরিজিনে খোলা অন্যান্য ট্যাবকে প্রভাবিত করতে পারে, কারণ একই IndexedDB ডেটাবেস একাধিক ট্যাব দ্বারা একই সাথে অ্যাক্সেস করা যায়। ফলস্বরূপ, ব্রাউজারগুলো সাধারণত কোনো IndexedDB ট্রানজ্যাকশনের মাঝখানে বা এমন কোনো API ব্যবহার করার সময় পেজ ক্যাশ করার চেষ্টা করে না যা অন্য পেজকে প্রভাবিত করতে পারে।

বিভিন্ন API-এর ব্যবহার কীভাবে একটি পেজের bfcache যোগ্যতার উপর প্রভাব ফেলে, সে সম্পর্কে আরও বিস্তারিত জানতে, 'Optimize your pages for bfcache ' দেখুন।

বিএফক্যাশ এবং আইফ্রেম

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

তবে, যখন বিএফক্যাশ থেকে মূল ফ্রেমটি পুনরুদ্ধার করা হবে, তখন এমবেডেড আইফ্রেমগুলিও সেই অবস্থাতেই পুনরুদ্ধার হবে, যে অবস্থায় পৃষ্ঠাটি বিএফক্যাশে প্রবেশ করেছিল।

যদি কোনো এমবেডেড আইফ্রেম এমন এপিআই ব্যবহার করে যা বিএফক্যাশ (bfcache) ব্যবহারে বাধা দেয়, তাহলে মেইনফ্রেমের বিএফক্যাশ ব্যবহারও ব্লক হয়ে যেতে পারে। এটি এড়ানোর জন্য মেইনফ্রেমে পারমিশন পলিসি (Permissions Policy) সেট করা অথবা sandbox attributes) ব্যবহার করা যেতে পারে।

বিএফক্যাশ এবং সিঙ্গেল পেজ অ্যাপস (এসপিএ)

যেহেতু bfcache ব্রাউজার-পরিচালিত নেভিগেশনের সাথে কাজ করে, তাই এটি একটি সিঙ্গেল-পেজ অ্যাপ (SPA)-এর ভেতরের 'সফট নেভিগেশন'-এর জন্য কাজ করে না। তবে, অ্যাপটিকে আবার শুরু থেকে সম্পূর্ণভাবে পুনরায় চালু না করে, কোনো SPA-তে ফিরে যাওয়ার ক্ষেত্রেও bfcache সাহায্য করতে পারে।

bfcache পর্যবেক্ষণ করার জন্য API

যদিও বিএফক্যাশ (bfcache) একটি অপটিমাইজেশন যা ব্রাউজারগুলো স্বয়ংক্রিয়ভাবে করে থাকে, তবুও ডেভেলপারদের জন্য এটি কখন ঘটছে তা জানা গুরুত্বপূর্ণ, যাতে তারা এর জন্য তাদের পেজগুলো অপটিমাইজ করতে পারে এবং সেই অনুযায়ী যেকোনো মেট্রিক বা পারফরম্যান্স পরিমাপ সমন্বয় করতে পারে

bfcache পর্যবেক্ষণ করার জন্য ব্যবহৃত প্রধান ইভেন্টগুলো হলো pageshow এবং pagehide পেজ ট্রানজিশন ইভেন্ট , যেগুলো বেশিরভাগ ব্রাউজার দ্বারা সমর্থিত।

নতুন পেজ লাইফসাইকেল ইভেন্ট— freeze এবং resume —পেজ যখন bfcache-এ প্রবেশ করে বা তা থেকে বেরিয়ে যায়, তখন এবং আরও কিছু পরিস্থিতিতে, যেমন সিপিইউ ব্যবহার কমানোর জন্য যখন কোনো ব্যাকগ্রাউন্ড ট্যাব ফ্রিজ হয়ে যায়, তখনও ডিসপ্যাচ করা হয়। এই ইভেন্টগুলো শুধুমাত্র ক্রোমিয়াম-ভিত্তিক ব্রাউজারগুলিতে সমর্থিত।

bfcache থেকে কখন একটি পৃষ্ঠা পুনরুদ্ধার করা হয় তা পর্যবেক্ষণ করুন।

পেজটি প্রাথমিকভাবে লোড হওয়ার সময় এবং যখনই পেজটি বিএফক্যাশ (bfcache) থেকে রিস্টোর করা হয়, তখন load ইভেন্টের ঠিক পরেই pageshow ইভেন্টটি ফায়ার হয়। pageshow ইভেন্টের একটি persisted ) প্রপার্টি আছে, যা পেজটি বিএফক্যাশ থেকে রিস্টোর করা হলে ট্রু ( true এবং অন্যথায় false হয়। সাধারণ পেজ লোড এবং বিএফক্যাশ রিস্টোরের মধ্যে পার্থক্য করার জন্য আপনি persisted প্রপার্টিটি ব্যবহার করতে পারেন। উদাহরণস্বরূপ:

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    console.log('This page was restored from the bfcache.');
  } else {
    console.log('This page was loaded normally.');
  }
});

যেসব ব্রাউজার পেজ লাইফসাইকেল এপিআই (Page Lifecycle API) সমর্থন করে, সেগুলোতে বিএফক্যাশ (bfcache) থেকে পেজ পুনরুদ্ধার করার সময় ( pageshow ইভেন্টের ঠিক আগে) এবং যখন কোনো ব্যবহারকারী একটি ফ্রোজেন (frozen) ব্যাকগ্রাউন্ড ট্যাবে পুনরায় প্রবেশ করে, তখন রেজিউম resume ) ইভেন্টটি ফায়ার হয়। যদি আপনি কোনো পেজ ফ্রোজেন হওয়ার পরে তার স্টেট আপডেট করতে চান (যার মধ্যে বিএফক্যাশে থাকা পেজগুলোও অন্তর্ভুক্ত), তাহলে আপনি resume ইভেন্টটি ব্যবহার করতে পারেন, কিন্তু যদি আপনি আপনার সাইটের বিএফক্যাশ হিট রেট (bfcache hit rate) পরিমাপ করতে চান, তাহলে আপনাকে pageshow ইভেন্টটি ব্যবহার করতে হবে। কিছু ক্ষেত্রে, আপনার উভয়ই ব্যবহার করার প্রয়োজন হতে পারে।

bfcache পরিমাপের সর্বোত্তম অনুশীলন সম্পর্কে বিস্তারিত জানতে, “bfcache কীভাবে অ্যানালিটিক্স এবং পারফরম্যান্স পরিমাপকে প্রভাবিত করে” দেখুন।

কখন একটি পৃষ্ঠা bfcache-এ প্রবেশ করছে তা পর্যবেক্ষণ করুন।

কোনো পৃষ্ঠা আনলোড হলে অথবা ব্রাউজার যখন সেটিকে বিএফক্যাশে (bfcache) রাখার চেষ্টা করে, তখন pagehide ইভেন্টটি ফায়ার হয়।

The pagehide event also has a persisted property. If it's false , you can be confident a that page isn't about to enter the bfcache. However, persisted being true doesn't guarantee that a page will be cached. It means the browser intends to cache the page, but there may be other factors that make it impossible to cache.

window.addEventListener('pagehide', (event) => {
  if (event.persisted) {
    console.log('This page *might* be entering the bfcache.');
  } else {
    console.log('This page will unload normally and be discarded.');
  }
});

Similarly, the freeze event fires immediately after the pagehide event if persisted is true , but that only means the browser intends to cache the page. It might still have to discard it for a number of reasons explained later.

Optimize your pages for bfcache

Not all pages get stored in bfcache, and even when a page does get stored there, it won't stay there indefinitely. It's critical that developers understand what makes pages eligible (and ineligible) for bfcache to maximize their cache-hit rates.

The following sections outline the best practices to make it as likely as possible that the browser can cache your pages.

Never use the unload event

The most important way to optimize for bfcache in all browsers is to never use the unload event. Ever!

The unload event is problematic for browsers because it predates bfcache and many pages on the internet operate under the (reasonable) assumption that a page won't continue to exist after the unload event has fired. This presents a challenge because many of those pages were also built with the assumption that the unload event would fire any time a user is navigating away, which is no longer true (and hasn't been true for a long time ).

So browsers are faced with a dilemma, they have to choose between something that can improve the user experience—but might also risk breaking the page.

On desktop, Chrome and Firefox have chosen to make pages ineligible for bfcache if they add an unload listener, which is less risky but also disqualifies a lot of pages. Safari will attempt to cache some pages with an unload event listener, but to reduce potential breakage it won't run the unload event when a user is navigating away, which makes the event very unreliable.

On mobile, Chrome and Safari will attempt to cache pages with an unload event listener since the risk of breakage is lower due to the fact that the unload event has always been extremely unreliable on mobile. Firefox treats pages that use unload as ineligible for the bfcache, except on iOS, where all browsers use the WebKit rendering engine, and so behave like Safari.

Instead of using the unload event, use the pagehide event. The pagehide event fires in all cases where the unload event fires, and it also fires when a page is put in the bfcache.

In fact, Lighthouse has a no-unload-listeners audit , which will warn developers if any JavaScript on their pages (including that from third-party libraries) adds an unload event listener.

Due to its unreliability, and the performance impact for bfcache, Chrome is looking to deprecate the unload event .

Use Permission Policy to prevent unload handlers being used on a page

Sites that don't use unload event handlers can ensure these are not added by using a Permissions Policy .

Permissions-Policy: unload=()

This also prevents third parties or extensions from slowing the site down by adding unload handlers and making the site ineligible for the bfcache.

Only add beforeunload listeners conditionally

The beforeunload event won't make your pages ineligible for bfcache in modern browsers' bfcache but previously it did and it is still unreliable, so avoid using it unless absolutely necessary.

Unlike the unload event, however, there are legitimate uses for beforeunload . For example, when you want to warn the user that they have unsaved changes they'll lose if they leave the page. In this case, it's recommended that you only add beforeunload listeners when a user has unsaved changes and then remove them immediately after the unsaved changes are saved.

না
window.addEventListener('beforeunload', (event) => {
  if (pageHasUnsavedChanges()) {
    event.preventDefault();
    return event.returnValue = 'Are you sure you want to exit?';
  }
});
This code adds a beforeunload listener unconditionally.
করুন
function beforeUnloadListener(event) {
  event.preventDefault();
  return event.returnValue = 'Are you sure you want to exit?';
};

// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
  window.addEventListener('beforeunload', beforeUnloadListener);
});

// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
  window.removeEventListener('beforeunload', beforeUnloadListener);
});
This code only adds the beforeunload listener when it's needed (and removes it when it's not).

Minimize use of Cache-Control: no-store

Cache-Control: no-store is an HTTP header web servers can set on responses that instructs the browser not to store the response in any HTTP cache. It's used for resources containing sensitive user information, such as pages behind a login.

Although bfcache is not an HTTP cache, historically, when Cache-Control: no-store is set on the page resource itself (as opposed to any subresource), browsers have chosen not to store the page in bfcache so any pages using Cache-Control: no-store may not be eligible for bfcache. There is work underway to change this behavior for Chrome in a privacy-preserving manner.

Since Cache-Control: no-store restricts a page's eligibility for bfcache, it should only be set on pages that contain sensitive information where caching of any sort is never appropriate.

For pages that need to always serve up-to-date content—and that content does not contain sensitive information—use Cache-Control: no-cache or Cache-Control: max-age=0 . These directives instruct the browser to revalidate the content before serving it, and they don't affect a page's bfcache eligibility.

Note that when a page is restored from bfcache, it is restored from memory, not from the HTTP cache. As a result, directives like Cache-Control: no-cache or Cache-Control: max-age=0 are not taken into account, and no revalidation occurs before the content is displayed to the user.

This is still likely a better user experience, however, as bfcache restores are instant and—since pages don't stay in the bfcache for very long—it's unlikely that the content is out of date. However, if your content does change minute-by-minute, you can fetch any updates using the pageshow event, as outlined in the next section.

Update stale or sensitive data after bfcache restore

If your site keeps user state—especially any sensitive user information—that data needs to be updated or cleared after a page is restored from bfcache.

For example, if a user navigates to a checkout page and then updates their shopping cart, a back navigation could potentially expose out-of-date information if a stale page is restored from bfcache.

Another, more critical example is if a user signs out of a site on a public computer and the next user clicks the back button. This could potentially expose private data that the user assumed was cleared when they logged out.

To avoid situations like this, it's good to always update the page after a pageshow event if event.persisted is true :

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Do any checks and updates to the page
  }
});

While ideally you would update the content in place, for some changes you may want to force a full reload. The following code checks for the presence of a site-specific cookie in the pageshow event and reloads if the cookie is not found:

window.addEventListener('pageshow', (event) => {
  if (event.persisted && !document.cookie.match(/my-cookie)) {
    // Force a reload if the user has logged out.
    location.reload();
  }
});

A reload has the advantage that will still preserve the history (to allow forward navigations), but a redirect may be more appropriate in some cases.

Ads and bfcache restore

It may be tempting to try to avoid the use of bfcache to serve a new set of ads on each back/forward navigation. However, as well as having a performance impact, it is questionable whether such behavior leads to better ad engagement. Users may have noticed an ad they intended to return to click but by reloading rather than restoring from the bfcache they not be able to. Testing this scenario—ideally with an A/B test—is important before making assumptions.

For sites that do want to refresh ads on bfcache restore, then refreshing just the ads on the pageshow event when event.persisted is true allows this to happen without impacting the page performance. Check with your ad provider but here is one example on how to do this with Google Publishing Tag .

Avoid window.opener references

In older browsers, if a page was opened using window.open() from a link with target=_blank , without specifying rel="noopener" , the opening page would have a reference to the window object of the opened page.

In addition to being a security risk , a page with a non-null window.opener reference can't safely be put into bfcache, because that could break any pages attempting to access it.

As a result, it's best to avoid creating window.opener references. You can do this by using rel="noopener" whenever possible (note, this is now the default in all modern browsers). If your site requires opening a window and controlling it through window.postMessage() or directly referencing the window object, neither the opened window nor the opener will be eligible for the bfcache.

Close open connections before the user navigates away

As mentioned previously, when a page is held in the bfcache, it pauses all scheduled JavaScript tasks and resumes them when the page is taken out of the cache.

If these scheduled JavaScript tasks are only accessing DOM APIs—or other APIs isolated to just the current page—then pausing these tasks while the page is not visible to the user is not going to cause any problems.

However, if these tasks are connected to APIs that are also accessible from other pages in the same origin (for example: IndexedDB, Web Locks, WebSockets) this can be problematic because pausing these tasks may prevent code in other tabs from running.

As a result, some browsers won't attempt to put a page in bfcache in the following scenarios:

If your page is using any of these APIs, we strongly recommend closing connections and removing or disconnecting observers during the pagehide or freeze event. That allows the browser to safely cache the page without the risk of affecting other open tabs.

Then, if the page is restored from the bfcache, you can reopen or reconnect to those APIs during the pageshow or resume event, or have them always automatically reopen using the error or close events. Ensure you do no open multiple connections if using multiple events.

The following example shows how to ensure that pages using IndexedDB are eligible for bfcache by closing an open connection in the pagehide event listener:

let dbPromise;
function openDB() {
  if (!dbPromise) {
    dbPromise = new Promise((resolve, reject) => {
      const req = indexedDB.open('my-db', 1);
      req.onupgradeneeded = () => req.result.createObjectStore('keyval');
      req.onerror = () => reject(req.error);
      req.onsuccess = () => resolve(req.result);
    });
  }
  return dbPromise;
}

// Close the connection to the database when the user leaves.
window.addEventListener('pagehide', () => {
  if (dbPromise) {
    dbPromise.then(db => db.close());
    dbPromise = null;
  }
});

// Open the connection when the page is loaded or restored from bfcache.
window.addEventListener('pageshow', () => openDB());

Test to ensure your pages are cacheable

Chrome DevTools can help you test your pages to ensure they're optimized for bfcache, and identify any issues that might prevent them from being eligible.

To test a page:

  1. Navigate to the page in Chrome.
  2. In DevTools, go to Application -> Back-forward Cache .
  3. Click the Run Test button. DevTools then tries to navigate away and back to determine whether the page can be restored from bfcache.
Back-forward cache panel in DevTools
The Back-forward Cache panel in DevTools.

If the test is successful, the panel reports "Restored from back-forward cache".

DevTools reporting a page was successfully restored from bfcache
A successfully restored page.

If it's unsuccessful, the panel indicates the reason why. If the reason is something you can address as a developer, the panel marks it as Actionable .

DevTools reporting failure to restore a page from bfcache
A failed bfcache test with an actionable result.

In this example, the use of an unload event listener makes the page ineligible for bfcache. You can fix that by switching from unload to using pagehide :

করুন
window.addEventListener('pagehide', ...);
না
window.addEventListener('unload', ...);

Lighthouse 10.0 also added a bfcache audit , which performs a similar test. For more information, see the bfcache audit's docs .

How bfcache affects analytics and performance measurement

If you use an analytics tool to measure visits to your site, you might notice a decrease in the total number of pageviews reported as Chrome enables bfcache for more users.

In fact, you're likely already underreporting pageviews from other browsers that implement bfcache, because many popular analytics libraries don't measure bfcache restores as new pageviews.

To include bfcache restores in your pageview count, set listeners for the pageshow event and check the persisted property.

The following example shows how to do this with Google Analytics. Other analytics tools likely use similar logic:

// Send a pageview when the page is first loaded.
// This happens by default just by loading gtag
gtag('config', 'TAG_ID');

window.addEventListener('pageshow', (event) => {
  // Send another pageview if the page is restored from bfcache.
  if (event.persisted) {
    gtag('event', 'page_view');
  }
});

Measure your bfcache hit ratio

You may also want to measure whether the bfcache was used, to help identify pages that are not utilizing the bfcache. This can be done by measuring the navigation type for page loads:

// Send a navigation_type when the page is first loaded.
// To do this disable the default pageview so you can manually send it
// supplemented with the additional detail.
gtag('config', 'TAG_ID', { send_page_view: false });
gtag('event', 'page_view', {
   'navigation_type': performance.getEntriesByType('navigation')[0].type;
});

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Send another pageview if the page is restored from bfcache.
    gtag('event', 'page_view', {
      'navigation_type': 'back_forward_cache';
    });
  }
});

Calculate your bfcache hit ratio using the counts for back_forward navigations and back_forward_cache navigations.

It is important to realize that there are a number of scenarios, outside of the site owners control, when a Back/Forward navigation won't use the bfcache, including:

  • when the user quits the browser and starts it again
  • when the user duplicates a tab
  • when the user closes a tab and reopens it

In some of these cases the original navigation type may be preserved by some browsers and so may show a type of back_forward despite these not being Back/Forward navigations.

Even without those exclusions the bfcache will be discarded after a period to conserve memory.

So, website owners shouldn't be expecting a 100% bfcache hit ratio for all back_forward navigations. However, measuring their ratio can be useful to identify pages where the page itself is preventing bfcache usage for a high proportion of back and forward navigations.

The Chrome team has added the NotRestoredReasons API to help expose the reasons why pages don't use bfcache, so developers can improve their bfcache hit rates. The Chrome team has also added navigation types to CrUX making it possible to see the number of bfcache navigations even without measuring it yourself.

কর্মক্ষমতা পরিমাপ

bfcache can also negatively affect performance metrics collected in the field , specifically metrics that measure page load times.

Since bfcache navigations restore an existing page rather than initiate a new page load, the total number of page loads collected will decrease when bfcache is enabled. What's critical, though, is that the page loads being replaced by bfcache restores would likely have been some of the fastest page loads in your dataset. This is because back and forward navigations, by definition, are repeat visits, and repeat page loads are generally faster than page loads from first time visitors (due to HTTP caching , as mentioned earlier).

The result is fewer fast page loads in your dataset, which will likely skew the distribution slower—despite the fact that the performance experienced by the user has probably improved!

There are a few ways to deal with this issue. One is to annotate all page load metrics with their respective navigation type : navigate , reload , back_forward , or prerender . This lets you continue to monitor your performance within these navigation types, even if the overall distribution skews negative. We recommend this approach for non-user-centric page load metrics like Time to First Byte (TTFB) .

For user-centric metrics like the Core Web Vitals , a better option is to report a value that more accurately represents what the user experiences.

Impact on Core Web Vitals

Core Web Vitals measure the user's experience of a web page across a variety of dimensions (loading speed, interactivity, visual stability), and since users experience bfcache restores as faster navigations than full page loads, it's important that the Core Web Vitals metrics reflect this. After all, a user doesn't care whether or not bfcache was enabled, they just care that the navigation was fast!

Tools that collect and report on the Core Web Vitals metrics, like the Chrome User Experience Report , treat bfcache restores as separate page visits in their dataset. And while there aren't dedicated web performance APIs for measuring these metrics after bfcache restores, you can approximate their values using existing web APIs:

  • For Largest Contentful Paint (LCP) , use the delta between the pageshow event's timestamp and the timestamp of the next painted frame, because all elements in the frame will be painted at the same time. In the case of a bfcache restore, LCP and FCP are the same.
  • For Interaction to Next Paint (INP) , keep using your existing Performance Observer, but reset the current INP value to 0.
  • For Cumulative Layout Shift (CLS) , keep using your existing Performance Observer, but reset the current CLS value to 0.

For more details on how bfcache affects each metric, see the individual Core Web Vitals metric guides pages . For a specific example of how to implement bfcache versions of these metrics, refer to the PR adding them to the web-vitals JS library .

The web-vitals JavaScript library supports bfcache restores in the metrics it reports.

অতিরিক্ত সম্পদ