tl;dr
You control how much data you are willing to process each frame. If a packet is too big, break it into smaller cells and process them one at a time (i.e one each frame). If you get a lot of small packets than split the group into chunks and limit the amount of information processing that is done each frame. The client does not need all the information; the server does so only send the client information that is crucial to the view. The rest could be handled on the server.
Handling resource intensive tasks
While maintaining user perceived performance
preface:
The issue:
You have a limited amount of resources to complete a certain task. You also wish to complete this task in a specific time frame (i.e 1/30 seconds). Using HTML5 does not allow you the same freedom and efficiency that you'd get with a native client. If you need more efficiency in utilizing resources you should seriously consider a native client or a plugin based Engine like Unity3D.
Possible sollutions:
1. Offloading client responsibilities to the server:
The client could be a dumb terminal in the extreme case, only accepting and uploading input from the user as in:
player attacks Goblin Lord
and downloading simple view related instructions from the server as in
display kobold thief at (someX, someY)
or play attack animation for Goblin[i]
and when you go towards this pattern, the client does not need to receive much data.
2. Caching reusable data in advance:
You can store data on the client-side by uploading it during the game startup. If you know for instance that there are Kobolds and Goblins in your game, you can have the client download their stats and store them in memory in advance. Do not make their stats random, give them classes, levels or whatever modifiers you need but keep things organized and known in advance so you don't have to upload everything to the client on the fly. Instead send a small packet like Kobold Archer Lvl 11
. Obviously using Enum
s for the actual code that is sent to the client to save more bandwidth.
3. Optimizing your code with a profiler:
Today it is a lot easier to optimize JS code with things like Chrome DevTools that can be used in Chrome and the insights it provides are more valuable than answers in an online Q&A website. It can help you dig into your code and see what is slowing it down. You may often find there is a loop you can trim down or a function you could optimize that is taking too much CPU resources. You can use something like PageSpeed Insights for Chrome. Look for a profiler suitable for your developer needs and you will find something useful.
4. Break a long task into chunks
If a party of 5 Goblins and 7 Kobolds suddenly appear, you don't have to process all their info during one frame. You could break it down and process one task each frame. This kind of optimization depends on the frequency in which intensive tasks appear. It is often unwise to attempt to process all the information at once and it results in spikes in performance. Design your code around that. Create an array of tasks and only perform as much as you can lazily evaluating certain things only when you have free resources or they absolutely needed.
You could buffer things up. If the player line of sight is 9 x 9
squares then have the client aware of a 18 x 18
square and slowly handle entities that are out of site in the buffer zone before it becomes critical (be careful that users could exploit that for an unfair advantage).
5. Compromise where it doesn't hurt gameplay experience
Use the framework you are working with to the extent possible performance wise. If you need to trim down some of the functionality or data in the game, consider it as an option. Sometimes you can group similar data and send it once instead of duplicating the work to lessen the amount of bandwidth and CPU used and other times you can eliminate the data altogether. For instance, who needs to know the Wisdom attribute of a skeleton? Or the Charisma of a Kobold? Sometimes excessive data could be eliminated or postponed. For instance who cares what items monsters are carrying unless they were successfully slain.
6. The real answer (low level):
Most of what we can offer in reply to a High-level question is patterns , theories and design principles. The real answer is often in the code, if we don't see or know your code we can help in a High-level way but someone needs to get down and dirty and actually inspect the code. Sometimes code is not properly optimized. Often the answer is to further optimize a few pieces of code and ask about them specifically. If you are not sure about something ask for a code review in the appropriate site, ask a friend or use the chat system here. You can even ask a question about a concise selection of code put in context here.
7. Design your game around the problem:
If the problem occurs when lots of entities appear at once, make the game a bit sparser with less mobs and make each mob slightly more powerful instead. If the problem occurs because of players character population density, make another town that attracts some of the players to lessen the amount of players in one area at a time. Give missions that take players to a uniformly random area in the map.
Think what and where the problem occurs and make that far less likely to occur by slightly modifying or tweaking the game mechanics. Remember that games needs to be scalable so you may need to make some compromises or educated decisions about what you place and where.
For any additional details or specifics please use the comments.