Three.js From Zero · Article s14-07
Mobile Testing & Remote Debug
Mobile Testing & Remote Debug is Article s14-07 of Three.js From Zero, a MasterAllArts free interactive lesson for artists learning creative 3D on the web.
Season 14 · Article 07 · Setup & Tooling
Your Three.js scene runs at 144fps on your MacBook and 8fps on a 3-year-old Android. Most users are on Android. Mobile testing is the difference between "this is impressive" and "this is broken." Tools for testing on real devices and debugging them.
The four devices to actually test on
- iPhone SE / iPhone 8 — the floor of iOS performance. If it runs here, it runs everywhere on iOS.
- Pixel 4a or similar mid-range Android — average Android user.
- An iPad — different rendering pipeline (TBDR), reveals different bugs.
- Quest 2 browser — if you're targeting WebXR.
If you can't buy them all, BrowserStack and LambdaTest rent real devices for /month. Pick the bottom 4 — the top devices are easy mode.
iOS remote debugging
# On iPhone: Settings → Safari → Advanced → Web Inspector ON
# Connect phone to Mac via cable
# On Mac: Safari → Develop menu → [your iPhone] → [your tab]
# Now you have full DevTools attached to the iPhone Safari tab
Console logs, Network tab, Performance profiler — all running against the iPhone. The most important Mac dev step that nobody documents.
Android remote debugging
# On phone: Settings → About → tap "Build Number" 7 times to unlock dev mode
# Then Settings → Developer Options → USB Debugging ON
# Connect to Mac/PC via cable
# In Chrome on desktop: chrome://inspect
# Click "inspect" next to your tab — DevTools opens
Chrome's remote inspect is the most powerful mobile debug environment. Full DevTools, screen mirroring, and CPU/network throttling.
Performance throttling without a phone
Sometimes you just need to simulate slow. Chrome DevTools has it:
- Network → Throttling → Slow 3G — your assets load at 1.5Mbps with 600ms latency.
- Performance → CPU throttling → 6× slowdown — your CPU runs at iPad-Mini speed.
- Rendering → Frame rendering stats — overlay shows FPS, GPU memory, rendering performance.
Use these religiously. A demo that runs 60fps at 6× slowdown will run 60fps on most phones.
The "mobile mode" code path
const isMobile = window.matchMedia('(max-width: 800px), (pointer: coarse)').matches;
const renderer = new THREE.WebGLRenderer({
antialias: !isMobile, // disable AA on mobile, big win
powerPreference: isMobile ? 'low-power' : 'high-performance',
});
renderer.setPixelRatio(Math.min(window.devicePixelRatio, isMobile ? 1.5 : 2));
const shadowMapSize = isMobile ? 512 : 1024;
const particleCount = isMobile ? 30_000 : 200_000;
Detect once at startup. Swap in cheaper assets, smaller shadow maps, lower particle counts. Most users never know — they just see a fast site.
Touch controls
OrbitControls handles touch automatically but with bad defaults:
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.touches = {
ONE: THREE.TOUCH.ROTATE,
TWO: THREE.TOUCH.DOLLY_PAN, // two fingers = zoom + pan
};
Default single-finger drag rotates, two-finger pinch zooms. Don't override unless you have a strong reason — users have muscle memory.
iOS-specific gotchas
- Auto-play sound is blocked. WebAudio must be unlocked by a user gesture (any tap). Resume the audio context inside a click handler.
- WebXR requires "Add to Home Screen" on iOS for full-screen mode.
- OffscreenCanvas not supported on iOS < 16.4. Feature-detect and fall back to main-thread rendering.
- Low memory limits. iOS Safari kills tabs over ~1GB. Dispose aggressively.
Common first-time pitfalls
navigator.xr.requestSession(). Quest browser logs go to chrome://inspect/#devices on the connected PC.Exercises
- Test your demo on Slow 3G + 6× CPU. Aim for 30fps. If it can't reach that, your "mobile mode" code path needs to drop more.
- Remote debug iPhone Safari. Wire it up. Console.log from your phone, see it on your Mac. Click an element in DevTools, watch the iPhone highlight it.
- Build a perf overlay. A custom div in your scene showing FPS, draw calls, geometries. Toggle with a key. Ship it in dev only.
UP NEXT
S14-08 — Mixing HTML and WebGL → When DOM beats canvas, and the patterns that combine both.