Objects sit in places. You look around, then answer what was where. The 3D is the method, not decoration: the method of loci has been spatial since antiquity.
It is also a testbed. A room is one JSON file, five interchangeable runtimes draw the same scene, and every session reports frames, jank, input lag and load time from the device that ran it.
The question was not whether a browser can draw a room. It can. The question is what it costs to author one, hand it to development, put it in front of a phone, and measure how that phone handled it. LOCI exists to run that loop once, end to end.
A room is a box with furniture, places on the furniture, and objects on the places. Everything about it (size, light, furniture, places, objects, learning time, price tier) lives in one JSON file that planning edits in a visual editor with the same renderer beside it.
Four stages, each with a gate that stops errors propagating to the next.
A form with the live scene next to it. Furniture comes from presets whose positions are computed against the room size, and a place snaps onto a surface rather than being typed as coordinates.
Upload puts the room in review, not in front of users. Development opens it at a staged address that requires a login, and either approves or rejects with a reason planning reads.
Static files only. The user picks the room and the runtime on the first screen. Everything is precompressed with brotli and served that way.
Each session reports frames, worst 1%, jank, input lag, thermal drift, load breakdown and per-place results, split by runtime. Feedback is left on the section it is about, and acceptance is decided and recorded.
One Android phone, five runtimes, seven rooms, and one room built to break them. Ninety-six sessions on the same scenario, and the numbers came back from the device.
| Runtime | API | Draw calls | Frame | Hitch | First frame | Library |
|---|---|---|---|---|---|---|
| three.js | WebGL2 | 254 | 16.7 ms | 0.8% | 522 ms | 153 KB |
| Unity 6 | WebGL2 · wasm | 3 | 16.7 ms | 2.6% | 913 ms | 3.6 MB |
| Canvas 2D | Canvas 2D | 1,149 | 16.7 ms | 3.6% | 466 ms | 2.9 KB |
| Raw WebGL2 | WebGL2 | 4 | 16.7 ms | 20.8% | 241 ms | 4.6 KB |
| Raw WebGPU | WebGPU | 4 | 16.7 ms | 35.9% | 453 ms | 5.1 KB |
Galaxy Note10+ 5G (SM-N976N, Android 12), the Versailles room: 60 places, 817 pieces of furniture, 3.7 million triangles, over a local link so the network stays out of it. Hitch is the share of frames over 33 ms. Library size is what crossed the wire, brotli compressed. Median of two runs each.
The figures above are measurements. Below is what no measurement here supports.