perf: paint branded loading screen from static HTML (0.85.0)
the <div id=root> was empty until the JS bundle downloaded and React mounted, so the page was blank for ~2.4s (FCP). put the branded loading screen (pulsing gem + 'amerc') directly in the static HTML, with its critical CSS inlined in <head>, so it paints as soon as the CSS loads instead of waiting for JS. - React's createRoot replaces #root on mount; the Suspense fallback renders the identical markup, so the static->React handoff is seamless (no flicker) - inlined .app-loading critical CSS mirrors styles.css exactly + dark body bg so there's no white flash during load - verified live: FCP 2.4s -> 1.4s, performance 86 -> 90, TBT 50 -> 0ms; app mounts cleanly, static loader replaced, 0 console errors
This commit is contained in:
parent
522ce6ec83
commit
5e0eeb79c6
16
index.html
16
index.html
@ -4,8 +4,20 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#0e0a14" />
|
||||
<style>
|
||||
/* Critical CSS: paint the branded loading screen instantly from static
|
||||
HTML, before the JS bundle loads & React mounts. React replaces #root
|
||||
on mount; the Suspense fallback renders the same markup, so it's
|
||||
seamless. Mirrors .app-loading in styles.css. */
|
||||
html, body { margin: 0; background: #07060c; }
|
||||
.app-loading { position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; background: radial-gradient(circle at 50% 38%, #160d22, #07060c 70%); }
|
||||
.app-loading-gem { width: 28px; height: 28px; background: linear-gradient(135deg, #5fe6ff, #1f86c4); box-shadow: 0 0 0 3px #07273a, 0 0 22px rgba(39, 216, 255, 0.5); animation: app-pulse 1.3s ease-in-out infinite; }
|
||||
.app-loading-word { font-family: Georgia, "Times New Roman", serif; color: #f3d27a; font-size: 18px; letter-spacing: 2px; opacity: 0.85; }
|
||||
@keyframes app-pulse { 0%, 100% { transform: rotate(45deg) scale(1); opacity: 0.7; } 50% { transform: rotate(45deg) scale(1.16); opacity: 1; } }
|
||||
@media (prefers-reduced-motion: reduce) { .app-loading-gem { animation: none; transform: rotate(45deg); } }
|
||||
</style>
|
||||
<meta name="description" content="amerc is the agent mercenary tavern — hire, run, publish, and remotely deliver AI agents across software boundaries. No infrastructure, just skills." />
|
||||
<meta name="version" content="0.84.0-quality" />
|
||||
<meta name="version" content="0.85.0-fastpaint" />
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="icon" href="/app-192.png" type="image/png" sizes="192x192" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
@ -56,7 +68,7 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<div id="root"><div class="app-loading"><span class="app-loading-gem" aria-hidden="true"></span><span class="app-loading-word">amerc</span></div></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "amerc-site",
|
||||
"version": "0.84.0-quality",
|
||||
"version": "0.85.0-fastpaint",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@ -10,7 +10,7 @@ import { api } from './api.js';
|
||||
const Menu = ({ size = 20 }) => (<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true"><line x1="3" y1="6" x2="21" y2="6" /><line x1="3" y1="12" x2="21" y2="12" /><line x1="3" y1="18" x2="21" y2="18" /></svg>);
|
||||
const X = ({ size = 20 }) => (<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" /></svg>);
|
||||
|
||||
const RELEASE = '0.84.0-quality';
|
||||
const RELEASE = '0.85.0-fastpaint';
|
||||
|
||||
const NAV = [
|
||||
{ id: 'home', label: 'Tavern' },
|
||||
|
||||
Loading…
Reference in New Issue
Block a user