A vissza gomb gyorsaságának rejtett ellensége: így töröd el a bfcache-t

A böngésző bfcache-e teljes oldalt állíthat vissza a vissza gombnál. Az unload, az élő kapcsolatok és az elavult állapot mégis könnyen elrontja ezt.

A vissza gomb sok webhelyen valójában egy új oldalbetöltés: kérés, HTML, JavaScript és a szokásos várakozás. Pedig a böngészőnek van egy gyorsabb útja. A back/forward cache, röviden bfcache, a teljes előző oldalt memóriában tarthatja, így a vissza- vagy előrelépésnél nem újratölti, hanem folytatja azt.

A böngésző egy oldalt memóriába tesz, majd a vissza navigációkor onnan állítja helyre

Ez nem azonos a HTTP cache-sel. A bfcache a DOM-ot és a JavaScript heapet is megőrzi; a visszatérő oldalon a futás szünetből indul tovább, hálózati kérés nélkül. Emiatt egy hibás feltételezés könnyen előjön: ha az oldalról elnavigálnak, attól még nem semmisül meg. Ez egyszerre remek teljesítményoptimalizálás és életciklus-beli csapda.

A lap megáll, nem meghal

A bfcache-ba kerülő lap JavaScriptje megáll. A függő időzítők, promise-ok és feladatok sem futnak tovább, hanem visszaállításkor folytatódnak. Ezért például egy relatív időt megjelenítő komponens vagy egy lejárt bejelentkezés állapota visszatéréskor elavult lehet. A fő jelzés a pageshow esemény: annak persisted tulajdonsága igaz, ha az oldal bfcache-ből jött vissza.

window.addEventListener('pageshow', (event) => {
  if (!event.persisted) return;

  refreshSessionAndPrices();
  analytics.pageview({ navigation: 'back_forward_cache' });
});

Nem kell minden visszaállításkor teljes location.reload(). A jó kérdés inkább az, melyik adat nem maradhat régi: kosárösszeg, jogosultság, árfolyam, foglalási állapot vagy egy rövid életű token. Ezekhez elég egy célzott lekérés és a megfelelő UI frissítése. Kijelentkezésnél különösen fontos: egy megosztott gépen a vissza gomb ne mutathasson olyan személyes állapotot, amelyet a szerver már érvénytelenített.

Az unload sokszor a teljesítményhibád

A régi minta szerint az oldal távozásakor unload-ban takarítunk, adatot küldünk vagy leállítunk valamit. Ez már rossz illeszkedés a böngésző életciklusához. Az unload kivezetéséről szóló Chrome-dokumentáció szerint az esemény nem megbízható, és a kezelője a bfcache-t is ronthatja. Firefoxban az unload-kezelős lap nem jogosult bfcache-re; más motoroknál az esemény lefutása sem garantálható. Harmadik féltől betöltött analytics vagy widget is hozzáadhat ilyen kezelőt.

Telemetriához a visibilitychange a praktikus alap. A hidden állapot az utolsó megbízható pillanat, amikor a dokumentum még változhat; rövid, tűz-és-felejtsd jellegű méréshez a navigator.sendBeacon() épp erre készült.

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState !== 'hidden') return;

  const body = JSON.stringify({ type: 'page_hidden', path: location.pathname });
  navigator.sendBeacon('/events', body);
});

Ez nem tranzakciós sor: a sendBeacon() a böngészőnek átadott, kis POST-adat küldésére való, a válaszát nem olvashatod, és a sikeres visszatérés sem szerveroldali feldolgozási nyugta. Kritikus mentést ezért azonnal, a felhasználói műveletkor kell elvégezni, nem oldalelhagyásra halasztani. Mentetlen űrlaphoz a beforeunload maradhat, de csak addig, amíg tényleg van módosítás; mentés után vedd le a kezelőt.

Kapcsolatok: zárd, majd nyisd újra

A bfcache nem ígéret: a böngésző dönt a memória és az oldal viselkedése alapján. Különösen gyanúsak a több fülre ható, nyitva hagyott erőforrások. A web.dev útmutatója ilyen példaként említi a folyamatban lévő IndexedDB-műveletet, a WebSocket-et és a WebRTC-t. Ha a felhasználó már nem látja a lapot, pagehide-ban zárd le vagy szüneteltesd őket; pageshow-ban építsd vissza az élő kapcsolatot. A kettőt idempotensre írd, mert a lap normál betöltéskor is pageshow-t kap.

Érdemes azt is ellenőrizni, hogy a szerver véletlenül nem küld-e minden HTML-re Cache-Control: no-store-t. Ez érzékeny oldalnál helyes lehet, de sok esetben csak megszokás. A bfcache nem olvas HTTP cache-t és visszaállításkor nem revalidál, ezért a választás adatvédelmi döntés is. Általános, gyakran változó, de nem érzékeny tartalomnál inkább a no-cache vagy rövid max-age, valamint a pageshow-os célzott frissítés a jobb kombináció.

Mérd meg a vissza gombot is

Chrome-ban a DevTools Application paneljének Back-forward Cache nézete képes elnavigálni és visszatérni a lapra, majd megmutatja a blokkoló okokat. Ezt ne csak fejlesztéskor futtasd: új consent manager, chat widget vagy hibajelentő SDK is behozhat unload-kezelőt. Az analitikában a pageshow.persisted külön pageview-ja segít, hogy a gyors visszaállítás ne tűnjön el a mérésből, és a normál betöltésekkel se mosd össze.

A bfcache nem olyan optimalizálás, amelyhez új könyvtár vagy átírt router kell. Egy unload-keresés, a nyitott kapcsolatok életciklusának rendbetétele és néhány tudatos pageshow-frissítés sok oldalon elég. A jutalom nem jobb laborpontszám, hanem az a navigáció, amely a felhasználónak tényleg azonnalinak érződik.

Források

Leave a Reply

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük