reload by changing the src
Three versions of this now, and the reasons are worth keeping.
key={reloadToken} replaced the ELEMENT, so the panel went white between
documents. contentWindow.location.reload() kept the element but did not reliably
re-fetch. A changing src does both: the browser navigates the same element — so
it keeps painting the current document until the next commits — and the URL
differs, so nothing is served from cache.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+11
-19
@@ -227,29 +227,21 @@ export const SitePreview = ({
|
||||
}, [reloadToken, changed]);
|
||||
|
||||
/*
|
||||
Reload by NAVIGATING the frame, not by replacing it.
|
||||
Reloading, as a URL.
|
||||
|
||||
The frame used to carry `key={reloadToken}`, so a reload was a new element: React unmounted the old
|
||||
one and the panel went white until the new document arrived. On a page whose crop has just changed
|
||||
that is not instant — the site is asking av-club for a fresh ladder — so every framing adjustment
|
||||
flashed an empty panel for a second or two, which reads as the preview breaking.
|
||||
Three versions of this, and the reasons are worth keeping.
|
||||
|
||||
A browser keeps painting the current document while the next one is being fetched. So the same
|
||||
element stays, and the old page is on screen until the new one commits.
|
||||
`key={reloadToken}` replaced the ELEMENT, so React unmounted the old frame and the panel went white
|
||||
until the next document arrived — a second or two after a crop change, because the site is building
|
||||
a fresh ladder. That reads as the preview breaking.
|
||||
|
||||
Same origin, through the dev proxy, which is what makes `contentWindow` reachable at all.
|
||||
`contentWindow.location.reload()` kept the element but did not reliably re-fetch.
|
||||
|
||||
Skipped on the first run: the element has only just mounted and is already loading its document.
|
||||
A changing `src` does both: the browser navigates the SAME element, so it keeps painting the current
|
||||
document until the next one commits, and the URL is different so nothing is served from cache. The
|
||||
parameter means nothing to the site and is ignored.
|
||||
*/
|
||||
const first = useRef(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (first.current) {
|
||||
first.current = false;
|
||||
return;
|
||||
}
|
||||
frame.current?.contentWindow?.location.reload();
|
||||
}, [reloadToken, changed]);
|
||||
const reloadKey = `${reloadToken ?? 0}.${changed}`;
|
||||
|
||||
useEffect(() => {
|
||||
if (!loaded) return;
|
||||
@@ -379,7 +371,7 @@ export const SitePreview = ({
|
||||
applyTheme();
|
||||
setLoaded((n) => n + 1);
|
||||
}}
|
||||
src={`/api/dev-proxy/${port}/${path}`}
|
||||
src={`/api/dev-proxy/${port}/${path}?_=${reloadKey}`}
|
||||
title={`The site at /${path}`}
|
||||
className="border-0"
|
||||
// The device's real width, and the room's real height. No transform: see the note above.
|
||||
|
||||
Reference in New Issue
Block a user