I’m building a 3D Pac‑Man style game in React Three Fiber with @react-three/rapier physics and three-pathfinding navmesh. Visual performance is fine (draw calls under control, sprites batched), but CPU is the bottleneck from AI/pathfinding when many enemies are active. Frustum culling helped rendering, but didn’t reduce CPU much since logic still runs offscreen. What I’ve tried Reduced path update frequency and simplified paths on mobile. Basic AI LOD: slower ticks for distant enemies. Frustum check to skip per-frame raycasts and movement when offscreen. Separation/queueing to avoid overlap. Cached temp vectors to cut allocations. Still seeing high CPU when player moves quickly (many recalculations) and with dozens of enemies needing paths/avoidance.
Random suggestions in no particular order:
Move pathfinding to a worker…
Drastically cut the update frequency… like once per second per enemy max (staggered so they don’t ALL do it on the same frame)…
Use a coarser representation for pathfinding.. either a lower poly navmesh or some kind of coarser grid system…
Precompute paths for known common targets..
Use flow maps to direct pathing..
Do incremental pathfinding…
Make a queue for pathfinding so that you’re not slamming the main thread with multiple path finds per frame…
I think incremental and/or worker are the easiest.
Incremental is neat because enemies can start moving before a full path is even found.. and you can still kick off a bunch on a single frame.. but that depends on support from whatever library you’re using.
Might start by checking the polycount of your navmesh - ideally these triangles are large and fairly evenly sized.
You might also have a look at GitHub - isaac-mason/recast-navigation-js: WebAssembly port of Recast Navigation, a navigation mesh construction, path-finding, and spatial reasoning toolkit., it’s more sophisticated implementation with support for larger scenes (via tiled navmeshes) and for crowd pathfinding.
+1 to donmccurdy’s suggestion on polycount.
How many agents do you have?
For large numbers of agents one of the most impactful things you can do is seperate polygon node pathfinding (what sequence/corridor of nav mesh polys should an agent walk through, expensive) from string pulling (given a corridor of polys, what is the straight path through them, cheaper).
You can run polygon pathfinding infrequently, and run string pulling continuously for the next few polygons in an agent’s corridor.
Both navcat (my new pure javascript pathfinding library) and recast-navigation-js (wasm port of the c++ recastnavigation library) support this, and make it easy with high level crowd APIs ![]()
The crowd APIs in both libraries maintain a queue of polygon pathfinding queries, perform the pathfinding with time sliced APIs so computation is spread out over frames, and do string pulling for the next 3 polygons in a corridor every frame for agent steering.
Depending on your use case though, you might consider if you can get by with pathfinding on a 2D grid (not sure if I am following your use case correctly though with mention of 3D Pac-Man)