top | item 5286948

Server-side view or client-side MVC?

71 points| kailuowang | 13 years ago |kailuowang.blogspot.com | reply

DHH claimed that the development experience of client-side MVC is inferior compared to traditional Rails development. And he only gave two vague reasons - ruby and 'unnecessary' complexity. his article first shows some code comparison between the two paradigms to demonstrate the software design drive for client-side MV* and then talks about the business drive for client-side MVC(*) - interactivity.

58 comments

order
[+] olegp|13 years ago|reply
I would argue that the greatest benefit that client side MVC frameworks bring is that they enforce a clean RESTful API on the server. At a panel on MV* frameworks at HelsinkiJS last week somebody even said that they had to dramatically improve their API to make it work with Ember.

I myself have been working on https://starthq.com which started life as a single page app using AngularJS where most of the functionality was behind a login. It has now pivoted into a web app directory, where delivering the initial page quickly and in a way that Google can easily index is crucial & there's very little actual input validation or interactivity on the page. The nice thing is that despite this transition, the core API has remained the same regardless of where the view is rendered and the architecture is all the better for it.

Give it a go and see if you can tell which pages are rendered entirely on the server and which entirely on the client.

[+] Joeri|13 years ago|reply
I agree. You always need a clean api to allow for multiple front-ends and to have a secure boundary layer between trusted and untrusted data. Even if the rendering happens on the server, you should always start with an api.

I work on a 400 kloc app developed with a client-side mvc + web services architecture. The nice thing I've learnt about having a proper services api is that slapping another front-end on top of it is straightforward. We've had a relatively easy time building mobile apps thanks to having the service api ready. And because the core app is built around the same services, they are less likely to break.

[+] qschneier|13 years ago|reply
I agree and would rephrase it as client side frameworks help to enforce a clean and well defined API on the data, thus help to separate the business logic from representation / interaction, which is kind of the original goal of MVC.
[+] wildmusings|13 years ago|reply

     True this maybe achieved by refreshing the whole
     comments container   but what if he is also in the 
     middle of replying to another comment? What if we want 
     that new reply to show up in some sort of animation? 
You can achieve this pretty easily. You shouldn't be refreshing the entire comments container. If your views are well modularized, the comments container would render many _comment partials. You would simply render a new partial and insert it into the page appropriately. There's no reason to disrupt the rest of the page.

When you do client-side MVC, you end up having to duplicate a lot of your model and controller logic. This happens either explicitly, when you start defining relationships between models and how they should react to changes in associated models (e.g. backbone-relational), or implicitly, when it gets stuffed into view and "routing" logic (and leaving you with spaghetti code that's different but no better than jquery spaghetti). In rails views, you have access to the real model objects and you can still use AJAX to have a "single-page application" without the huge added complexity.

There's obviously a place for client-side MVC and that is RICH APPLICATIONS. Google Docs, Pandora, a photo editor, etc...

I think another factor is what your team looks like. If the person writing the models and controllers is the same guy making the front end, then you should probably stay away from client-side MVC. If you have dedicated frontend/javascript guys, then it might make more sense..

[+] kailuowang|13 years ago|reply
The point is that if you need granular partial refreshment, your javascript needs to be a lot more smart, like what to do when add/update/remove a comment - that is you end-up writing view logic both client-side and server-side. As stated in the article, the view logic needs access to both server-side data and client-side DOM, where it resides depends on which side the view logic requires more communication. The argument is that if you rethink HTML, then most web app should be designed in a way so that UI interaction significantly improves the UX. That's why we need client-side MV* to be an enabler for such re-thinking.
[+] lucaspiller|13 years ago|reply
Our main product is at it's heart nothing more than CRUD, except some of the forms are pretty complicated where you have to deal with nested record hell. Initially we just did everything the Rails way (i.e. jQuery and AJAX), but we have been looking to move stuff more MV* client side where possible.

I don't think either solution is really that great at the moment. Doing things MV* client side mean you duplicate views and potentially logic (we use decorators a lot which would need to be duplicated). Doing things via AJAX means you have to wait for the response before the view is updated (things like comments that will succeed - assuming validations are done before the request is made, and the server doesn't break - shouldn't have this delay).

One thing we have done that has helped, is instead of just attaching a load of jQuery events on random elements, is writing our Javascript in a similar style to Backbone views. Instead of writing everything with lots of nested events, we have a 'controller' responsible for each feature. On initialisation it binds to the DOM events it needs, and those call other methods on the controller. It also has it's own (local) state, so if we need to use the same feature multiple times on a page we can do with ease. It has allowed us to separate code better, and more importantly make it more legible. Here is an example:

https://gist.github.com/lucaspiller/5040983

[+] amikazmi|13 years ago|reply
The whole point of node.js/meteor is that you can share the code between client/server, so you dont have to duplicate anything, and have the access to the "real" model.
[+] smidwap|13 years ago|reply
1. Do not take this statement for granted: "When your page is simple, yes, you don't need that much interactivity. But the market will demand more and more functionality on that page." Simple, fast apps that don't overdose on interactivity seem like a better bet. The vast majority of problems being solved with software do not require the bells and whistles of Facebook & Gmail.

2. A huge aspect of choosing Rails or client-side MVC is productivity. If you're going to build a web app in Ruby, you're going to have to have somebody on your team that is good at Ruby. By layering a client-side MVC on top of that, you're now requiring javascript expertise. Your life is now twice as difficult.

3. It's amazing how powerful DHH's approach is. Just look at the new Basecamp. Does any part of that app feel slow, clumsy, and non-interactive? Absolutely not. I imagine myself being opening up the Basecamp codebase and "getting it" within a day. If you understand your constraints well, you can deliver amazing software with an order of magnitude less complexity.

[+] SkyMarshal|13 years ago|reply
>The vast majority of problems being solved with software do not require the bells and whistles of Facebook & Gmail.

Even with FB and Gmail, I've gotten the impression that neither of those is fully client or server-side, but rather highly optimized hybrids where component processing tasks are done wherever they can be with highest performance and lowest latency.

Both seem acutely conscious of comparative speeds of server-side rendering + internet latency vs. client-side rendering.

Not sure though, only an impression based on anecdotal evidence, anyone more familiar with their architectures?

[+] srid68|13 years ago|reply
My perspective on this debate is both client-side and server-side with only a backend API layer is required. The problem with most Js MVC frameworks are they enforce/make it easy to do client side rendering, but make it difficult/impossible to integrate server-side.

I have found that increasing the DOM element count leads to poor performance, hence too much view template loaded initially leads to unnecessary slowness. To mitigate this i started dynamic loading of view templates from the server, which lead to two different calls to the server, one to retrieve the json data and the other to retrieve the view template which makes some sense in certain use cases and sometime merging the data with the template makes it more performant and some case retrieving the template and data in a single call, but without merging is optimum. It all depends on the functionality required.

When you work in Old Android (Browser/WebView) devices, you will observe that using client side rendering and loading too much in the DOM leads to poor performance and it is better to render it on the server side and just use plain JavaScript to inject the rendered view to DOM, which leads to optimum performance.

[+] dougk16|13 years ago|reply
First, a white-tower point: if you look at the client and server as a whole, doing any kind of dynamic view generation on the server is a complete violation of MVC. You shouldn't tell the view how to view.

That said, server-side rendering is a product of historical inertia. Remember, client-side MVC is the way things were quite successfully done before the internets came along. However, browsers originally sucked at anything "client", so we developed languages and design patterns and libraries that slowly made the concept of a server-generated view tolerable, to the point where many sites (e.g. HN or Wikipedia) are actually better served by doing everything on the server. Now that javascript is powerful enough though (and we can cross-compile from languages better suited to complex application development), client-side MVC is unsurprisingly making a comeback.

[+] mckoss|13 years ago|reply
The search engines complicate the design choice of client-side vs. server-side MVC. While there are ways to hint search engines to retrieve searchable views of our application data, it adds an additional layer of complexity to your application. From my experiments, Google (or Bing) has yet to make a truly agnostic search engine when it comes to the design choice of client-side vs. server-side rendering. To do so, they would need to routinely emulate the full browser stack and javascript rendering on every page crawl. They do not yet do this. This is especially true when client-side anchor tags are used in URL's to represent client side navigation.
[+] beermann|13 years ago|reply
I have this argument with people a lot. I'm surprised that nobody talks about serving multiple applications from the same service layer. Sure, you can have a web app and then a separate API for mobile clients, but why not just have a RESTful interface that can be used by all of them?

This doesn't necessarily mean that you can't still do server-side views if you wanted to. But by separating the view rendering from the service layer you provide a bit more flexibility. Designed correctly, the argument becomes moot. Either you're creating a controller, models, and event callbacks on the server, or you're creating them on the client. Client-side javascript frameworks are getting so much better that it really just comes down to finding the best tools for your team.

[+] Kiro|13 years ago|reply
I don't understand how one is supposed to work with only a JSON back-end and rendering all the view with JavaScript. It's ok if it's only going into a list but what if you want to render the data in a complicated div structure? If you render it server-side it's very easy but with JS it becomes a mess, especially if there are lot of css classes that need to be added as well.
[+] orthecreedence|13 years ago|reply
I've been doing this for over a year now, and honestly, it's almost exactly the same on the front-end as it is in the back-end. You have templates (with variables, loop structures, etc)and you pass data into them and render. Same as back-end. With a decent front-end framework (backbone, spine, etc) the process can be simplified even more (like using a back-end framework).

I love this method because you can provide really snappy front-end experiences. It's also nice to focus on having a good solid API along with a consistent front-end, whereas splitting up your front-end between the server and the client can be more complicated than just doing it all in the client. Browsers are now capable to run the entire front-end, so why not let them?

[+] programminggeek|13 years ago|reply
Um, there is a time and place for client side MVC and there is a place for server side.

For example, if you want Google to crawl your stuff, go server side.

I think it's smart to look at it on a per-page or per app basis. Not everything should be client side MVC and not everything should be server side.

Do the right thing for your product.

[+] orthecreedence|13 years ago|reply
To add a note: if you have an app that you want Google to index but all of the other points weigh in on the all-JS app side, you can use PhantomJS to crawl/scrape/store your pages before a googlebot ever shows up. Yes, it's a pain in the ass, and yes it complicates your back-end...but it's a good way to have the best of both worlds.
[+] ymn_ayk|13 years ago|reply
Google started to understand javascript, didn't it?
[+] kaoD|13 years ago|reply
Server-side views are resource hogs. Client-side MVC is not SEO friendly and throws non-JS (or crappy) browsers away.

My bet would be both, but I couldn't find any framework that could render both server and client side templates based on the HTTP headers without enormous amounts of glue code.

[+] combataircraft|13 years ago|reply
Both.
[+] rozap|13 years ago|reply
I'm always curious as to why more people don't go with a hybrid approach. For a lot of my projects, it ends up being the simplest and cleanest solution. Maybe it doesn't really scale well when you have a lot of people working on the codebase that may or may not be familiar with both the backend and frontend, but when it's a one or two person project, I don't see the issue with it. It certainly keeps things simple and prevents duplicated logic.
[+] thibaut_barrere|13 years ago|reply
Exactly; for regular apps with little interaction needs, I start with a pure Rails back-end, and mix KnockOut.js only where relevant (for instance), or not at all.

For more UI-dynamic apps like https://www.wisecashhq.com, I go Rails JSON back-end + html rendering for skeleton, and KnockOut.js for the interactivity.

Now that DHH advocates "his way or the highway" isn't really a surprise :-)

[+] jbigelow76|13 years ago|reply
That was my immediate thought too. In the example cited the client side todo consumed a json list of all todo items. The server side is still going to be MVC just exsposing json instead of html.

Maybe I'm just splitting hairs, in general I agree with the author's premise.

[+] meaty|13 years ago|reply
I'm not sure how we'd go client side efficiently. We have 2500 views!
[+] shimms|13 years ago|reply
If you're referring to the cost of switching for an existing project with that many views, completely agree - changing any core component on a large project (regardless of how well de-coupled it is) presents challenges, and simply may not be worth it.

Or are you saying that it isn't possible to efficiently manage 2500 views using a client side framework?

[+] edwinyzh|13 years ago|reply
if needs_seo_friendly { use_server_side_view(); } else { use_client_side_mvc(); }

Server-side views are good for content-oriented websites, while client-side MVC's are good for function-oriented webapps that needs clean architecture.

PS, I like AngularJS as the client-side MVC framework, and I'm trying to find a way to better support it in my current project (http://liveditor.com).

[+] trungonnews|13 years ago|reply
Use Yahoo Mojito. Same MVC code on both server and client.
[+] papsosouid|13 years ago|reply
>It's the trend not because it looks new

Yes, it is. 90% of the client side javascript interfaces I've seen provide absolutely no benefit to the user, and often are outright worse than a normal html interface (twitter). Your complaints about RoR's terrible templates do not generalize to all server side template engines, so the whole thing should be framed accurately as a comparison of your preferred javascript mvc framework vs rails templates.

[+] nateabele|13 years ago|reply
Based on your comment, I'm guessing you've never actually implemented anything with a client-side JS framework.

Yes, strictly speaking, there's nothing inherent to client-side JS MVC frameworks that creates a better experience for end-users (over traditional server-side MVC + client-side Ajax + DOM manipulation, or whatever).

Where they do provide benefit is to developers, for whom it makes creating rich interfaces absurdly easy. Again, to be clear, this does nothing for users. Unless, of course, you consider that reduced barriers to implementing rich interactivity induce developers to use it create better user experiences, and that purpose-specific tools reduce the surface area for experience-disrupting bugs (which, statistically, you'd have more of, since you're operating at a lower level of abstraction and having to constantly repeat yourself [unless, of course, you decided to generalize all your Ajax & DOM manipulation and wrote a framework... oh wait]).

But hey, don't let me keep you from thinking whatever keeps you inside your comfort zone.

(Disclosure: the foregoing is based on ~1 year of experience developing applications with AngularJS).

[+] bluetidepro|13 years ago|reply
For the record, I think Twitter is one of the only sites out there that have done JS interfaces the right way. I love the Twitter interface over any Twitter client or the old html interface. I think it's much smoother and works great for their platform. But hey, I'm just one man! Ha