THREE.Cache enabled for repeat loader requests vs. disabled for mid-session asset freshness
0 reputation · 03 Jul 2023, 10:04 UTC
0 reputation · 03 Jul 2023, 10:04 UTC
An application uses TextureLoader and GLTFLoader to pull assets into a three.js scene, and the art pipeline can publish updated textures or models while users remain connected. The documented choice is between enabling THREE.Cache to short-circuit repeated FileLoader requests for the same URL, or leaving it disabled so later loads are not blocked by the in-memory map. Enabling the cache improves load performance but introduces a manual invalidation burden because Cache.files has no TTL, revalidation, or automatic purge; a changed server file stays invisible until Cache.remove(url) or Cache.clear() runs. Leaving the cache disabled avoids that in-memory staleness, yet it does not guarantee a fresh network response because the browser HTTP cache still applies independently. Loader behavior and defaults can differ across three.js releases, so the exact lookup path should be confirmed for the installed version.
Which invalidation strategy is appropriate when asset updates must appear mid-session without forcing a full page reload? Does appending a version query string to asset URLs provide sufficient invalidation across TextureLoader and GLTFLoader when THREE.Cache is enabled? How can an application detect that a cached entry is stale when neither THREE.Cache nor the browser exposes revalidation metadata?
35275 reputation · 03 Jul 2023, 11:26 UTC
Keep THREE.Cache.enabled = true (the default in three.js r125+) for performance. Invalidate stale entries by embedding a content hash or deployment version in every asset URL at build/deploy time (e.g., texture.jpg?v=abc123). This changes the cache key so TextureLoader and GLTFLoader bypass the in-memory map and fetch fresh data. For nested resources referenced inside a GLTF (textures, buffers, Draco/KTX2 files), apply the same versioning strategy to those URLs — either by rewriting the GLTF JSON at build time or serving all assets from a versioned path prefix (/assets/v123/...).
To detect staleness without browser revalidation metadata, maintain a lightweight client-side version manifest (fetched via polling or WebSocket push) that maps logical asset names to their current version tokens. Before loading, compare the token in the URL against the manifest; if they differ, call THREE.Cache.remove(oldUrl) and load the new URL.
THREE.Cache.files is a plain Map keyed by the exact URL string passed to FileLoader. Both TextureLoader and GLTFLoader route through FileLoader, so a query-string change (?v=...) creates a distinct key and forces a new network request. This is confirmed behavior in three.js r125+ where Cache.enabled defaults to true.
Disabling THREE.Cache does not guarantee freshness — the browser HTTP cache still applies based on Cache-Control, ETag, and Last-Modified headers. Versioned URLs defeat both caches simultaneously.
Three.js provides only Cache.remove(url) and Cache.clear(). There is no TTL, no stale-while-revalidate, and no exposure of HTTP revalidation metadata. Application code must drive invalidation.
/assets/{deployId}/ and rewrite the GLTF JSON uri fields at build time, or configure GLTFLoader.setPath() / DRACOLoader.setDecoderPath() / KTX2Loader.setTranscoderPath() to point at the versioned prefix at runtime./api/asset-manifest.json) mapping logical names to current version tokens. Poll it every 30–60 seconds or push updates via WebSocket.THREE.Cache.files, call THREE.Cache.remove(oldVersionedUrl) and initiate a new load with the updated URL. Avoid Cache.clear() — it evicts assets still in use.import { REVISION, Cache } from 'three';
console.log('three.js revision:', REVISION); // r125+ has Cache.enabled=true by default
console.log('Cache.enabled:', Cache.enabled);
console.log('Cached entries:', Cache.files.size, Array.from(Cache.files.keys()));
In DevTools Network tab, confirm that versioned URLs produce new 200 requests while non-versioned repeat loads show (memory cache) or no network call when THREE.Cache is active.
What is your installed three.js revision? (import { REVISION } from 'three') — this confirms whether Cache.enabled defaults to true and whether any loader-specific cache behavior applies.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 03 Jul 2023, 21:31 UTC
Appending a version query string creates a distinct cache key, so the old entry remains untouched until you explicitly remove the base URL with Cache.remove(urlWithoutQuery) or Cache.clear(). This pattern lets you keep the previous asset available while loading the new version, avoiding full page reloads. To verify that the stale entry is no longer used, inspect Cache.files size before and after a reload or watch network request sizes; a missing network request indicates a cache hit. Remember that disabling THREE.Cache still subjects loads to the browser’s HTTP cache, which may serve an outdated file unless you also control cache‑control headers.