fix: cache-bust asset URLs - the real reason the panel fix appeared not to work
Reported again as "code git still no go just a black box is it because I'm on firefox?"
It is NOT Firefox. Tested properly: installed Firefox 155 and drove the live server with
Playwright, authenticated. Result:
assets Firefox requested: theme/main.min.css?v=1790663824 <- versioned
applied panel rule: height: auto; max-height: 58vh <- the fix IS applied
dialog 193px | panel 138px | toolbar INSIDE | JS errors: none
CodeGit renders correctly in Firefox. Firefox was simply still running the OLD CSS.
WHY THE EARLIER FIX DIDN'T TAKE
Atheos emits asset URLs with no version:
<link rel="stylesheet" href="theme/main.min.css">
<script src="public/modules.min.js"></script>
Same path before and after a change, and originally no cache headers at all. So the browser
keeps its cached copy and never even asks the server. Changing the CSS server-side cannot
help when the browser isn't fetching it - which is why the previous Cache-Control fix was
necessary but NOT sufficient against a cache that was already poisoned.
FIX - versioned URLs
SourceManager::getTag() and the theme link in index.php now append the file mtime:
theme/main.min.css?v=1790663824
A changed file gets a NEW URL, so it is fetched immediately; an unchanged file keeps its URL
and stays cached. This works even against an already-stale cache, which headers alone cannot
do. The page itself is served no-store, so the next normal reload picks up new URLs
automatically - no hard refresh needed by the user.
Both parts are now in scripts/fix-panel-layout.sh (idempotent, verified):
1. Cache-Control: no-cache for *.css/*.js (revalidation; keeps 304s fast)
2. mtime-versioned asset URLs (the part that actually defeats a poisoned cache)
Tests: 45 passed, 0 failed, 1 accepted-risk
+ asset URLs must carry ?v= (guards against this regressing and silently hiding future fixes)
This commit is contained in:
+42
-10
@@ -280,19 +280,51 @@ after: panel 136px → toolbar top 256, dialog bottom 279 (inside)
|
||||
|
||||
## 5. 🟠 CSS/JS changes were invisible behind the browser cache
|
||||
|
||||
**Symptom:** a fix to the theme did not appear until a hard refresh — so the panel fix above looked
|
||||
like it had not worked at all.
|
||||
**Symptom:** a fix to the theme did not appear until a hard refresh — so the panel fix in §4 looked
|
||||
like it had not worked at all. Reported twice, the second time with "is it because I'm on Firefox?"
|
||||
|
||||
**Root cause:** Atheos serves `theme/main.min.css` and the generated `public/*.min.js|css` bundles
|
||||
from **stable URLs with no cache headers**, so nginx adds only `Last-Modified`/`ETag` and browsers
|
||||
legitimately reuse their cached copy.
|
||||
**It was not Firefox.** Verified in a real, scripted Firefox (155.0) against the live server with the
|
||||
fix applied:
|
||||
|
||||
**Fix:** nginx now sends `Cache-Control: no-cache, must-revalidate` for `*.css`/`*.js`. Note this does
|
||||
**not** disable caching — it forces **revalidation**, so normal loads still get a cheap 304 while any
|
||||
change is guaranteed to be picked up on the next load.
|
||||
```
|
||||
assets Firefox requested: theme/main.min.css?v=1790663824 <- versioned
|
||||
applied panel rule: height: auto; max-height: 58vh <- the fix
|
||||
dialog 193px | panel 138px | toolbar INSIDE | JS errors: none
|
||||
```
|
||||
|
||||
**If you ever see a stale UI again:** force a reload (Ctrl/Cmd-Shift-R). That is the first thing to try
|
||||
before assuming a fix failed.
|
||||
The panel rendered correctly and the Branch toolbar sat inside the modal. Firefox behaves identically
|
||||
to Chromium here; it was simply still running the **old cached stylesheet**.
|
||||
|
||||
**Root cause — stable asset URLs, with nothing to bust them.** Atheos emits:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="theme/main.min.css"> <!-- no version -->
|
||||
<script src="public/modules.min.js"></script> <!-- no version -->
|
||||
```
|
||||
|
||||
Same path before and after a change, and originally no cache headers at all. A browser therefore keeps
|
||||
its cached copy across an update, and never even asks the server. Changing the CSS on the server
|
||||
cannot fix that — the browser is not fetching it.
|
||||
|
||||
**Fix (two parts):**
|
||||
|
||||
1. **nginx** sends `Cache-Control: no-cache, must-revalidate` for `*.css`/`*.js`. This does **not**
|
||||
disable caching — it forces **revalidation**, so normal loads still get a cheap 304 while changes
|
||||
are picked up.
|
||||
2. **Versioned URLs.** `SourceManager::getTag()` and the theme link in `index.php` now append the
|
||||
file's mtime (`?v=<mtime>`). A changed file gets a **new URL** so it is fetched immediately; an
|
||||
unchanged file keeps its URL and stays cached.
|
||||
|
||||
Part 2 is the one that actually mattered here: it works **even against an already-poisoned cache**,
|
||||
which part 1 alone cannot do. Once the *page* refreshes (it is served `no-store`), every asset URL it
|
||||
references is new, so the stale CSS is bypassed with no manual clearing.
|
||||
|
||||
**If you ever see a stale UI again:** force a reload (Ctrl/Cmd-Shift-R). If that fixes it, this
|
||||
section is why.
|
||||
|
||||
**Forcing this one time:** if a browser holds an old copy, any of these work —
|
||||
Ctrl/Cmd-Shift-R, `about:blank` then back, a private window, or `rm -rf` the profile's cache. Or just
|
||||
change the file's mtime (`touch`) and the URL changes by itself.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user