You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The on-page overlay can now hide itself after a set time. A new "Auto-hide
after" select in the popup's Options section offers 3, 5, 10 or 20 seconds, or
"never" (the default, permanent - unchanged behaviour). The timer is armed the
first time the bar shows for a pageview; a soft navigation or new pageview
shows it again and restarts the countdown. Stored in chrome.storage.local
(fm_overlay_ttl) and applied live via storage.onChanged, like the other
overlay options.
Click the overlay to dismiss it for the current pageview (the bar is now
click-through-disabled and shows a pointer cursor). A soft-nav / new pageview
brings it back. Changing an overlay option (toggle, position, timeout) also
undoes a prior auto-hide or click-dismissal so the change is visible at once.
Add - smoxy page-cache verdict (S-Cache) per pageview
Documents served behind smoxy now show their page-cache verdict. The
DevTools network listener additionally captures the response headers of document requests; when S-Cache is present (or Server: smoxy), the
verdict is stored keyed by document URL (host + path, query ignored - the
tracker strips queries from u) and matched to pageviews by closest
navigation timestamp, so a reload keeps each pageview's own HIT/MISS.
Shown as a smoxy HIT|MISS|… badge in the pageview list and an S-Cache line in the detail head (with S-Cache-Reason when present),
color-coded like the popup's cache statuses (HIT good · MISS poor ·
EXPIRED/STALE/REVALIDATED warn · BYPASS purple). On a HIT the cache Age follows in parens (HIT (5min)) - Age is only meaningful when
the object actually came from the cache, and like every header here it is
optional (absent header, no parens). Entirely optional overall: pages not
behind smoxy render exactly as before. Works for tracked and basic-RUM
fallback pageviews alike.
Opt-in. The whole smoxy feature sits behind a popup toggle ("smoxy
s-cache", chrome.storage.local key fm_smoxy, default off): it gates
the panel's DevTools capture and display, the service worker's webRequest
storage, and the overlay cell - applied live, and switching it off sweeps
every stored verdict. While a smoxy verdict is shown, the CDN cache
row/cell is suppressed in popup and overlay: smoxy IS the page cache in
front of the origin here, showing both would be redundant. The popup's
toggles (overlay + smoxy) now live in a collapsed "Options" <details>
section, keeping the popup compact until expanded; the UI labels the
header lower-case ("s-cache").
Popup and on-page overlay show the verdict too - without DevTools open.
New webRequest permission (+ <all_urls> host permissions, no new install
warning beyond the existing all-sites one): the service worker observes the
top-level document response and keeps only Server / S-Cache / S-Cache-Reason / Age per tab (doc:<tabId> in session storage; a
non-smoxy document clears the entry, tab close reclaims it). The popup adds
a "smoxy page cache" row to its cache section; the overlay (tap-relay.js)
pulls the verdict from the SW at document_start (__fmDocGet, with retries
for the async write) and renders a smoxy HIT (5min)|MISS cell next to
CDN/Origin - the overlay now also appears on smoxy pages without fastmon.
Bodies are never read on this path; PRIVACY.md documents the header
observation.
Overlay polish. The vitals cells are always rendered (n/a until
measured) so the bar keeps a stable width instead of jumping as values pop
in. Basic-RUM fallback snapshots now feed the overlay too (display-only __fm_rum__ event from rum-tap.js; the records still reach the service
worker exactly once), so TTFB/LCP/CLS fill in on pages without fastmon. The
"fastmon" brand text is gone; instead the fastmon logo appears - and
ONLY when a real collector beacon proved fastmon runs on the page, so the
logo doubles as the "fastmon detected" indicator (RUM-fallback/smoxy-only
overlays carry no branding). The asset is the white logo mark without the
dark tile (logos/logo-dark.svg minus its background rect) - the tiled icon
read as a dark blob on the dark overlay bar - inlined as an SVG data URI: chrome.runtime.getURL() would require web_accessible_resources, which
lets any page probe for the extension.
Add - overlay position option
The on-page overlay's corner is now configurable: top-left, top-right,
bottom-right (default), or bottom-left, via a select in the popup's Options
section (chrome.storage.local key fm_overlay_pos). tap-relay.js applies
the corner live through storage.onChanged - no reload needed. Invalid
stored values fall back to bottom-right.
Fix - "Unchecked runtime.lastError: No tab with id: …"
Fire-and-forget chrome.runtime.sendMessage calls in tap-relay.js and
rum-tap.js now pass a callback that reads runtime.lastError (marking it
checked). Without one, Chrome logs the error whenever the implicit response
cannot be delivered back to the sending tab - which happens routinely,
because the terminal beacon/snapshot fires during pagehide and the tab is
gone a moment later. The service worker's __fmDocGetsendResponse is
guarded the same way (the asking document can vanish while the storage read
is in flight).
chrome.action.setIcon/setTitle switched from promise+.catch to the callback form reading lastError - the promise variant still produced
"Unchecked runtime.lastError" logs on some Chrome versions when the tab id
was already gone. And tap-relay's smoxy pull no longer messages from prerendered documents (it waits for prerenderingchange): discarded
prerenders were a steady source of vanishing synthetic tab ids.
Note: "Uncaught (in promise) TypeError: Failed to fetch" entries in the
extension error list are the PAGE's own failed fetches, attributed to us
because tap-main.js wraps window.fetch - known and deliberately not
silenced (see 2026.7.6 / 2026.7.7).
Add - basic-RUM fallback for pages without the fastmon snippet
Pages without a fastmon snippet now show basic RUM data plus Server-Timing
instead of an empty panel. A new ISOLATED-world content script
(rum-tap.js) measures a minimal picture straight from the browser's
Performance APIs - navigation timing (TTFB/DNS/TCP/response/DOM-interactive/
load/transfer size/protocol/nav type), FCP/first-paint, LCP, session-window
CLS, a web-vitals-style INP estimate, connection info, and the navigation
entry's Server-Timing - and ships snapshots through the same
service-worker path as real beacons. Snapshots are shaped like collector
beacons (same wire keys, synthetic rum-… pvid, lifecycle init → loaded → update → hidden → terminated), so vitals scorecards, the
field table, charts, compare, and overview render them unchanged.
Fallback pageviews are clearly marked: a basic RUM badge in the list and
a hint banner in the detail explain that the values are measured locally
by the inspector, not by tracker beacons. The popup shows the same fallback
summary (CWV + cache status + Server-Timing) with a matching hint; the
toolbar icon stays gray (it still signals "fastmon active" only).
Real beacons always win: fastmon presence is detected via the in-page
tap's event, collection stops immediately, and if fallback snapshots were
already emitted, a one-shot rum-drop retracts the fallback pageview and
popup summary. As a belt-and-braces, the panel also drops a still-open
fallback pageview when a real beacon for the same document arrives via the
network path (e.g. the pixel fallback).
Everything stays local (chrome.storage.session); PRIVACY.md documents the
Performance-API read. Tests cover ingest, merge, banner/badge, supersede, and
the rum-drop retraction.