From 120c7ec4e1614ac17449b87060590cab170aed99 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Wed, 7 Oct 2026 13:56:23 +0700 Subject: [PATCH] Docs: the web hosting guide matches what the build ships (#164, #165, #174, #180) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - #174: the file names are fixed (effectcraft_web.js, effectcraft_web_bg.wasm, worker.js, sw.js…), not content-hashed, so the guide's year-long immutable caching kept returning visitors on the old release after an in-place upgrade. The guide, nginx example, _headers and .htaccess now revalidate (no-cache) the .wasm, .js and index.html, and suggest a versioned path for longer caching. The file table lists the real files. - #180: the .wasm is about 58 MB (17 MB gzip, 10 MB Brotli) for v0.3.1, not 13 MB / 5 MB; docs/web.md's 38 MB figure is updated too. - #165: preferences live in the origin's browser storage (OPFS, IndexedDB or memory), not localStorage. - #164: relative URLs come from the page itself (and package.sh's check), not a Trunk.toml that doesn't exist. The iframe example's title no longer says image editor. Co-Authored-By: Claude Opus 5.5 --- docs/web.md | 8 +++++--- packaging/web/.htaccess | 6 ++---- packaging/web/README.md | 44 +++++++++++++++++++++++++---------------- packaging/web/_headers | 5 +++-- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/docs/web.md b/docs/web.md index 623b6dd9..104cbc2c 100644 --- a/docs/web.md +++ b/docs/web.md @@ -31,9 +31,11 @@ isolated like a production deployment should be. Any static server works (`python3 -m http.server -d target/web/dist 8765`); it must serve `.wasm` as `application/wasm`. Service workers need a secure context: `https://`, or `http://localhost` / `127.0.0.1`. -The release `.wasm` is about 38 MB before `wasm-opt` (code: the effects, codecs, the expression -engine and the UI; data, mostly the bundled fonts; function names for readable panics). Served -compressed it is a fraction of that, and the service worker caches it after the first visit. +The release `.wasm` is about 58 MB before `wasm-opt` (v0.3.1; code: the effects, codecs, the +expression engine and the UI; data, mostly the bundled fonts; function names for readable +panics). Served compressed it is about 17 MB with gzip or 10 MB with Brotli, and the service +worker caches it after the first visit. Its name doesn't change between releases, so hosts +revalidate it rather than caching it for long (`packaging/web/README.md`). On other targets the web crate holds only its portable storage model (`store.rs`, unit-tested by `cargo test --workspace`); `cargo xtask wasm` (part of `cargo xtask ci`) checks the whole crate, diff --git a/packaging/web/.htaccess b/packaging/web/.htaccess index 7b7e6e18..60f128d3 100644 --- a/packaging/web/.htaccess +++ b/packaging/web/.htaccess @@ -7,10 +7,8 @@ AddType text/javascript .js - - Header set Cache-Control "public, max-age=31536000, immutable" - - + # The file names don't change between releases: revalidate them (HOSTING.md). + Header set Cache-Control "no-cache" diff --git a/packaging/web/README.md b/packaging/web/README.md index 230525ba..0a1f56fe 100644 --- a/packaging/web/README.md +++ b/packaging/web/README.md @@ -6,29 +6,38 @@ static site in `effectcraft-web-/`: | File | What it is | |---|---| | `index.html` | The page. It loads everything through relative URLs. | -| `effectcraft-web-.js` | wasm-bindgen glue (generated, ES module) | -| `effectcraft-web-_bg.wasm` | The app, about 13 MB, or 5 MB with compression | +| `effectcraft_web.js` | wasm-bindgen glue (generated, ES module) | +| `effectcraft_web_bg.wasm` | The app: about 58 MB, about 17 MB with gzip and 10 MB with Brotli (v0.3.1) | +| `snippets/…/js/host.js` | Browser glue (storage, audio, workers) | +| `worker.js`, `audio-worklet.js` | Render and frame workers, and audio playback | +| `sw.js`, `manifest.webmanifest`, icons | Offline install: the service worker and the app manifest | | `_headers`, `.htaccess` | Sample header rules for Netlify/Cloudflare Pages and Apache | There is no server-side code. Upload the folder's contents anywhere that serves static files. ## Any path works -All URLs in `index.html` are relative (`public_url = "./"` in `apps/effectcraft-web/Trunk.toml`), -so the site works at a domain root (`https://example.com/`), under a prefix -(`https://example.com/tools/effectcraft/`) and from a CDN bucket. The asset names carry a content -hash, so they can be cached forever. Only `index.html` needs revalidation. +All URLs in `index.html` are relative: the page is written that way +(`apps/effectcraft-web/web/index.html`), and `package.sh` refuses a build with root-absolute +URLs. So the site works at a domain root (`https://example.com/`), under a prefix +(`https://example.com/tools/effectcraft/`) and from a CDN bucket. + +The file names are the same in every release (`effectcraft_web_bg.wasm` and so on), so browsers +must revalidate them: a long-lived cache would keep returning visitors on the old version after +you upgrade in place. Revalidation is cheap (an unchanged file answers `304 Not Modified`), and +the service worker keeps the app for offline use after the first visit. To cache the files for +longer, serve each release from its own versioned path (`/effectcraft/0.4.0/`). ## Required server settings - **MIME type:** serve `.wasm` as `application/wasm`. Browsers refuse to stream-compile it under any other type, and the app then loads slowly or not at all. Serve `.js` as `text/javascript`. Most hosts already do both. For nginx, check that `mime.types` has `application/wasm wasm;`. -- **Compression:** turn on gzip or Brotli for `.wasm`, `.js` and `.html`. That takes the - download from about 13 MB to about 5 MB. You can also precompress (`brotli -k *.wasm`) and let - the server send `Content-Encoding: br`. -- **Caching:** `Cache-Control: public, max-age=31536000, immutable` on the hashed `.wasm` and - `.js` files, and `no-cache` on `index.html`. +- **Compression:** turn on gzip or Brotli for `.wasm`, `.js` and `.html`. For v0.3.1 that takes + the download from about 58 MB to about 17 MB (gzip) or 10 MB (Brotli). You can also + precompress (`brotli -k *.wasm`) and let the server send `Content-Encoding: br`. +- **Caching:** `Cache-Control: no-cache` (revalidate) on `index.html`, `sw.js` and the `.wasm` + and `.js` files, since their names don't change between releases (see above). - **HTTPS:** WebGPU (and the clipboard) only work in a secure context, which means `https://` or `http://localhost`. Over plain HTTP elsewhere, the app falls back to WebGL2. - **No special isolation headers:** EffectCraft doesn't use `SharedArrayBuffer`, so it doesn't @@ -43,8 +52,7 @@ location /effectcraft/ { types { application/wasm wasm; text/javascript js; text/html html; } gzip on; gzip_types application/wasm text/javascript text/html; - location ~* \.(wasm|js)$ { add_header Cache-Control "public, max-age=31536000, immutable"; } - location ~* index\.html$ { add_header Cache-Control "no-cache"; } + location ~* (\.(wasm|js)|index\.html)$ { add_header Cache-Control "no-cache"; } } ``` @@ -55,7 +63,7 @@ Local test: `python3 -m http.server 8765` inside the folder, then open http://lo ```html