Files
FacereWeb/deploy/conf.d/default.conf
Knowit b510b33628 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>
2026-05-03 03:17:38 +08:00

56 lines
1.7 KiB
Plaintext

server {
listen 80;
server_name web.facere.cc _;
root /usr/share/nginx/html;
index facere.html index.html;
charset utf-8;
# Deny access to repo metadata, deploy scripts/configs, and dotfiles
location ~ /\.git { deny all; return 404; }
location ~ /\. { deny all; return 404; }
location ^~ /deploy/ { deny all; return 404; }
location = /deploy-pull.sh { deny all; return 404; }
location = / {
try_files /facere.html =404;
}
# The HTML entrypoint must NOT cache long — it carries the
# ?v=… cache-busting tags that everything else relies on.
location = /facere.html {
add_header Cache-Control "public, max-age=0, must-revalidate";
expires off;
}
location / {
try_files $uri $uri/ /facere.html;
}
# CSS/JS: long-cache + immutable. URLs are versioned with ?v=… so
# each deploy is a brand-new key; anything served here will never
# need to be re-fetched in a session.
location ~* \.(?:css|js|jsx)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
types { text/css css; application/javascript js; application/javascript jsx; }
try_files $uri =404;
}
# Static media: long cache + immutable (filenames change when content does).
location ~* \.(?:png|jpe?g|gif|webp|avif|svg|mp4|webm|woff2?|ttf|otf|ico)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
try_files $uri =404;
}
gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;
gzip_vary on;
access_log /var/log/nginx/facere.access.log;
error_log /var/log/nginx/facere.error.log;
}