As you've discovered, nodejs is spectacularly unsuitable for running computations that take more than a millisecond or two. It has a single main loop that it uses to invoke callbacks, events, and await operations (promise resolution or rejection).
If you call a long-running function from one of those callbacks / events / whatever, it blocks the main loop until it finishes and so nodejs waits to handle the next operation. This makes your application feel slow and janky. This kind of one-event-at-a-time operation is inherent to Javascript.
There are a few ways to manage this. By far the best is to figure out how to get your client code, running on your users' machines, to do the heavy computation like game physics. That means rethinking the design of your system. It also means you stick your users with the power bill for your physics engine, always a smart move if you get a lot of users.
You can switch to a language with lightweight threads to program your server. Java and C# are reasonable choices, and golang will do too.
You can break up your long running computations and do them asynchronously, something like this:
async function comp () {
while (computationNotDone) {
await doChunkOfComputation()
}
}
The await operation lets node reactivate its main loop. Your chunks of computation take their turn with other events and callbacks.
You can also try node Worker Threads. Explaining that is beyond the scope of a StackOverflow answer.
Check this out How can I prevent while loop freeze node.js?