How are online chess engines' architecture designed? I recently build a chess engine using javascript (https://github.com/Ram-the-coder/ai-chess-engine-v2). It runs on the browser - because of this when the chess engine is computing the best move, the webpage gets unresponsive. So I thought if I move the processing to the server, then I can eliminate the unresponsiveness. But if I do that then I've to maintain the game state for each client of the server. The size of the game state I think is in mega bytes as it includes the hash tables.

Another problem I faced in keeping the processing on the client-side is that the processing speed becomes dependent on the client's device.

How are such online chess engines usually built?

I don't think storing the game state in memory is good as the server has to serve many clients. Maybe storing in a database in the same server might work...

If I use a client-server architecture, won't I be restricted to serve one client request per server at a time? If yes, how are online chess engines able to serve unlimited clients at the same time?
Lichess uses WebAssembly (Wasm) - as is stated on the analysis page (“Stockfish 10+ WASM in local browser”). Wasm is the obvious thing to use, as it runs on the client side but is faster than JavaScript.

Running Stockfish in a web browser is usually done using Niklas Fiekas’ Wasm+JavaScript port of Stockfish, which is what Lichess uses. This consists of a Wasm file stockfish.wasm containing the engine itself, and a smaller JavaScript file stockfish.wasm.js that controls the use of the engine. (There is also a large file stockfish.js that is used as a fallback on browsers that lack native Wasm support.)