Perf: pre-compile JSX, prod React, WebP assets, immutable cache
This is the big "make scrolling smooth" pass — the biggest wins live in cold-start, not in the scroll loop itself, but a fast cold start means GSAP starts in a non-thrashing state and stays there. - Drop @babel/standalone (~3MB) from the page entirely. app.jsx is pre-compiled to app.js via deploy/build.sh; the browser loads the compiled bundle directly. JSX-in-browser was running babel transform on every page load, which is brutal on phones. - Switch React UMD bundles from .development to .production.min: ~1.1MB → ~140KB, no dev-mode warnings/checks in the hot path. - Add `defer` + `<link rel=preload as=script>` for the React/GSAP CDN scripts so they fetch in parallel with HTML parse, execute in order after DOM is ready, and don't block first paint. - Re-encode the three 1.4–1.8MB PNG backgrounds as WebP at full size (~190KB total) plus a 900px-wide mobile variant (~52KB total). Mobile preload links use `media=` so phones never download the full-size variants. - Move bg-image URLs from inline JSX styles into styles.css so the mobile media query can swap them in cleanly. - nginx: long-cache versioned static assets (Cache-Control immutable, 1 year) since URLs already carry ?v=… cache busters; keep the HTML itself on must-revalidate so the version pointer can update. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
38
facere.html
38
facere.html
@@ -5,29 +5,43 @@
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>FACERE — Hardware Design Agent</title>
|
||||
|
||||
<!-- Establish CDN connections early -->
|
||||
<link rel="preconnect" href="https://unpkg.com" crossorigin />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link rel="dns-prefetch" href="https://unpkg.com" />
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;600&family=VT323&display=swap" rel="stylesheet" />
|
||||
|
||||
<link rel="stylesheet" href="styles.css?v=20260503-mobile2" />
|
||||
<link rel="stylesheet" href="styles.css?v=20260503-perf" />
|
||||
|
||||
<!-- Preload background images -->
|
||||
<link rel="preload" as="image" href="assets/exterior-factory.png" />
|
||||
<link rel="preload" as="image" href="assets/factory-interior.png" />
|
||||
<link rel="preload" as="image" href="assets/pcb-chip.png" />
|
||||
<!-- Preload critical scripts so they fetch in parallel with the CSS -->
|
||||
<link rel="preload" as="script" href="https://unpkg.com/react@18.3.1/umd/react.production.min.js" crossorigin />
|
||||
<link rel="preload" as="script" href="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js" crossorigin />
|
||||
<link rel="preload" as="script" href="https://unpkg.com/gsap@3.12.5/dist/gsap.min.js" crossorigin />
|
||||
<link rel="preload" as="script" href="https://unpkg.com/gsap@3.12.5/dist/ScrollTrigger.min.js" crossorigin />
|
||||
<link rel="preload" as="script" href="app.js?v=20260503-perf" />
|
||||
|
||||
<!-- Preload background images. Mobile gets the smaller variant via media= -->
|
||||
<link rel="preload" as="image" href="assets/exterior-factory.webp" media="(min-width: 761px)" fetchpriority="high" />
|
||||
<link rel="preload" as="image" href="assets/factory-interior.webp" media="(min-width: 761px)" />
|
||||
<link rel="preload" as="image" href="assets/pcb-chip.webp" media="(min-width: 761px)" />
|
||||
<link rel="preload" as="image" href="assets/exterior-factory-mobile.webp" media="(max-width: 760px)" fetchpriority="high" />
|
||||
<link rel="preload" as="image" href="assets/factory-interior-mobile.webp" media="(max-width: 760px)" />
|
||||
<link rel="preload" as="image" href="assets/pcb-chip-mobile.webp" media="(max-width: 760px)" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<!-- React -->
|
||||
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
||||
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
||||
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
||||
<!-- Production React (no dev warnings, ~140KB total vs ~1.1MB for dev builds) -->
|
||||
<script src="https://unpkg.com/react@18.3.1/umd/react.production.min.js" integrity="sha384-DGyLxAyjq0f9SPpVevD6IgztCFlnMF6oW/XQGmfe+IsZ8TqEiDrcHkMLKI6fiB/Z" crossorigin="anonymous" defer></script>
|
||||
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js" integrity="sha384-gTGxhz21lVGYNMcdJOyq01Edg0jhn/c22nsx0kyqP0TxaV5WVdsSH1fSDUf5YJj1" crossorigin="anonymous" defer></script>
|
||||
|
||||
<!-- GSAP + ScrollTrigger -->
|
||||
<script src="https://unpkg.com/gsap@3.12.5/dist/gsap.min.js"></script>
|
||||
<script src="https://unpkg.com/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
|
||||
<script src="https://unpkg.com/gsap@3.12.5/dist/gsap.min.js" defer></script>
|
||||
<script src="https://unpkg.com/gsap@3.12.5/dist/ScrollTrigger.min.js" defer></script>
|
||||
|
||||
<script type="text/babel" src="app.jsx?v=20260503-mobile2"></script>
|
||||
<!-- Pre-compiled from app.jsx (see deploy/build.sh). No babel-standalone in browser. -->
|
||||
<script src="app.js?v=20260503-perf" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user