Hey everyone — built LeetCity, a tool that takes your LeetCode profile stats
and generates a procedural 3D city out of them. The more problems you’ve solved (and their difficulty/topics), the more your city grows.
Live: https://leetcity-lac.vercel.app/
Built with three.js for the 3D city generation/rendering. Would love feedback on the visuals and performance, especially on lower-end devices — still tuning the procedural generation logic.
Happy to answer questions about how the generation works if anyone’s curious.
Two separate things here, worth splitting because they have different fixes.
The 504. I pulled your bundle: there’s no direct client-side call to LeetCode’s API — the only references to their site are plain UI links (/problems/, /tag/, /u/). That makes sense, since LeetCode doesn’t send CORS headers for arbitrary origins, so a browser-side fetch() to their GraphQL endpoint would just fail. Which means the profile lookup is almost certainly proxied through your own Vercel API route server-side. Vercel serverless functions have a hard execution ceiling — 10s on the Hobby tier, and even on Pro it stays capped unless you explicitly raise maxDuration. A 504 coming from your domain (not from LeetCode’s) points at that function hitting its own timeout while waiting on their response, which is known to be slow or occasionally rate-limit requests that don’t look like a real browser session (no cookies, generic headers). Worth checking the actual duration in your Vercel function logs before the 504 — if it’s landing right at 10s every time, that confirms it’s the ceiling and not a one-off network blip.
Low-end performance. The basics are already in place — InstancedMesh for the buildings, some LOD logic. The next lever, and usually the cheapest one, is devicePixelRatio: rendering at the device’s native ratio (2–3x on a lot of Android/iOS glass) is a quadratic fill-rate cost, and it’s invisible in your own testing because desktop DPRs are lower. renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5)) on detected low-tier devices is usually a bigger win than anything on the geometry side. After that: worth checking whether every building “type” gets its own InstancedMesh (a draw call per type) versus one shared buffer with a per-instance attribute driving the variation — with enough distinct building types the draw-call count creeps back up even with instancing in place.
Are you capping devicePixelRatio right now, or letting it run native? And is the 504 consistent on every load, or intermittent — that tells you whether you’re hitting a hard ceiling or LeetCode’s endpoint being flaky under load.