Node.js – Dividing Responsibilities Between Client and Server

angularjsclient-serverclient-sidenode.jsserver-side

I'm working on a Web app that uses node.js on the server and AngularJS on the client. I'm new to Angular, but enables writing client-side applications that can be more self-contained than some other approaches.

Here is the scenario. On the server, I query a DB and then transform the results into a list of nodes and edge objects. These objects are sent to the client (browser), and the client displays them as a graph.

The code to parse the query results and build the graph is pretty generic and I expect to use it again subsequent apps. It can stay on the server. However, a lot of the code could be moved to the client because it is specific the sigma.js package that displays the graph.

Part of me wants to offload the processing the client. There is also talk of ditching sigma.js for the next application we build, so shoving it into the client sounds pretty appealing.

However, the client is already feels bloated and complicated. I could use something like the decorator pattern to keep the sigma.js specific code encapsulated while leaving room for more representations.

Which direction should I go? What should I taking into consideration?

Best Answer

Which direction should I go? What should I taking into consideration?

I cannot tell you which direction to go because that will require careful consideration of your problem domain, end users and some testing. However, I can help you figure out what to take into consideration.

Load Balancing

Your application servers are fixed. You might have 2, 3 or even 4, but whatever the number, you have a certain number. You can scale horizontally by adding servers, but there is a direct linear cost to that.

On the other hand, you have N clients. Each user who visits your site has their own CPU and memory. In terms of executing your code, that is free CPU and memory :) Hard to pass that up.

Your clients also provide a level of isolation. The work of one client does not impact the work of another in regard to client-side code. If everything executed on the server, one HTTP request going awry can bog down a server that is shared by many users.

Security

Don't trust the client to do computations that affect data that gets shared with other users unless that computation is derived from data they have entered anyway. For example, it would be fine to use JavaScript in the browser to convert the user's entered "05-15-2014" into an ISO date, but if the server needs to record the time the client performed some action, don't ask the client to do supply the time. Just capture the time on the server when that request occurs.

Performance

Browsers can be slow to do a lot of number crunching. Until the recent JavaScript browser war, JavaScript in general was a slow language, not due to issues with the language, just the runtime implementations. If the server can calculate something using a nice fast server-grade CPU and send it down, that may perform better than letting the client do it.

Predictability

Client machines vary. There are users running Safari on a Mac, Chrome on a Windows 7 64-bit machine with 8 GB of RAM and users running IE8 on Windows XP 32-bit. You can't predict how your client-side code will perform because there are major factors outside of your control. Your servers on the other hand, are very much under your control. You can monitor their performance and scale them up or down as needed to balance performance and costs.

Bandwidth

Calculating something on the server may be faster, but if you end up having to push a large data set down to the client over the Internet, not only is there a latency component to that, but you are likely billed by bandwidth usage. Therefore, if you have a cheap calculation that results in a large data set (let's say an array of all even numbers up to 1 million), let the client do it.

Monitoring

Your servers are under your control and therefore you can monitor their performance. If requests to a specific page are returning results to the client after 5 seconds, it is easier to detect and debug that on your servers. There are tools and mechanisms to monitor client-side performance, but the trade-offs and complexities are usually higher (like how do you report the data back to a central place and report on it?), like:

  1. How do you report the data back to a central place?
  2. Performance hit of executing additional code
  3. For clients where the performance is extremely bad, you may not even get the measurements, which biases your metrics because the worst performance is what you need to know the most about.

Server-side performance can be monitored via log files.