Skip to content
Writing
Front-end3DPerformanceSecurity

Immersive, Fast and Secure: You Don't Have to Pick Two

How I deliver 3D-rich websites that load fast on a mid-range phone and run under a strict security policy, with AI in the workflow and the bar unchanged.

· 3 min readOn the map: Front-end

The usual assumption is that you get to pick two: immersive, fast or secure. In my experience the trade-off rarely comes from the technology. It comes from decisions made in the first week, and it goes away when those decisions are made on purpose.

Here is how I deliver all three.

3D has to earn its place

Before choosing tools, I ask what the scene does that an image can't. A product the visitor can turn, a space they can move through, data with real depth: those justify a GPU. A spinning logo behind the headline doesn't.

If the page reads the same with the scene replaced by a still image, ship the image first and treat the scene as an enhancement.

Fast by design

Slow 3D sites are usually slow for three reasons: the scene sits on the critical path, the assets are uncompressed, and the render loop never stops.

  • Poster first. A pre-rendered frame ships with the HTML and is what Largest Contentful Paint measures. Three.js, React Three Fiber and the loaders live in their own chunk, loaded after first paint or when the scene nears the viewport.
  • Compressed assets. glTF with Draco or Meshopt geometry, and KTX2 textures that stay compressed in GPU memory, which is where phones run out first.
  • Render on demand. A scene that isn't moving should cost nothing: on-demand rendering in React Three Fiber, a capped pixel ratio, and a loop that pauses offscreen.

Then I measure on a mid-range phone, not a laptop: LCP, interactions under 200 ms, and frame time.

The latest features, used with intent

View Transitions for continuity between pages. CSS scroll-driven animations, which can run off the main thread. Server components and streaming, so content arrives before the JavaScript does. WebGPU where it exists, since Three.js's WebGPURenderer falls back to WebGL 2 where it doesn't. GSAP for choreography CSS can't express.

Each one is progressive enhancement. Take it away and the page still works.

Secure by default

  • A strict Content Security Policy: nonces instead of inline-script allowances, and an allowlist naming every origin the page talks to.
  • Security headers: HSTS, frame-ancestors against clickjacking, a tight Referrer-Policy, and a Permissions-Policy that switches off camera, microphone and location unless a feature needs them.
  • Sessions in httpOnly, Secure, SameSite cookies, never tokens in localStorage, where any injected script can read them.
  • Nothing secret in the bundle. Whatever ships to the browser is public.
  • Sanitized content. Rich text from the CMS is cleaned on the server before it renders.
  • Watched dependencies: lockfiles, automated updates and vulnerability scans in CI, with third-party scripts self-hosted where possible.

Where 3D and security collide

This is the part most write-ups skip. Draco, Meshopt and KTX2 decoders run as WebAssembly, and Three.js's Draco and KTX2 loaders start Web Workers from blob URLs. A strict policy blocks both, and the common fix is 'unsafe-eval', which also re-enables eval() for every script on the page.

The precise fix is narrower. 'wasm-unsafe-eval' allows WebAssembly and nothing else, worker-src 'self' blob: allows the decoder workers, and the decoder files are self-hosted rather than loaded from a third-party CDN. The scene works and the policy stays strict.

Proof on every release

Budgets and security checks run in CI: bundle size, Core Web Vitals in a lab run, response headers, the policy itself, and a dependency audit. A release that fails doesn't ship. In production, CSP violation reports show what the policy blocked before any user notices.

Where AI fits

I use AI throughout development: scaffolding scenes, writing loaders and asset scripts, generating tests, reading performance traces, reviewing security configuration. It is fast on the mechanical work and confidently wrong where it matters most. Ask it to make a CSP error go away and it adds 'unsafe-eval'. Ask it for a scene and it leaves the render loop running.

So AI-written code meets the same budgets, the same checks and the same review as everything else. The tools changed. The bar didn't.

What leading ten senior developers taught me

  • Standards hold only when a machine enforces them. A check that fails the build gets respected; a guideline on a wiki gets skimmed.
  • Defaults beat heroics. A starter project with the policy, headers and budgets already wired makes fast and secure the easy path.
  • Seniors need reasons, not rules. Decisions written down with their context get followed. Unexplained ones get relitigated.
  • The bar is whatever you approve. Every review either holds the standard or quietly lowers it.

Immersive, fast and secure isn't a trade-off. It's a set of defaults, chosen early and enforced on every release.