

Server-side view or client-side MVC? - kailuowang
http://kailuowang.blogspot.com/2013/02/server-side-view-or-client-side-mv.html
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.
======
olegp
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
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.

------
marcoperaza

         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
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.

------
smidwap
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
_> 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?

~~~
encoderer
Facebooks architecture here is impressive and you can read more about it, they
call it Bigpipe. (Of course this is probably, to some extent, out-dated by
now).

------
srid68
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
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
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.

~~~
bdicasa
I wouldn't use a client side MVC framework for pages that need to be crawled.
I find them great for webapps that require a user to login.

~~~
mckoss
It's a shame to have to arbitrarily make this tradeoff. There is nothing
inherent in saying that apps that desire rich client-side navigation are 100%
the apps the DON'T require search engine support.

Google does have a spec for hash-bang URL's to enable both to be present in a
single app. Unfortunately, it's clunky and not universally implemented.

------
beermann
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
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
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?

~~~
Kiro
Thanks. What template engine are you using?

~~~
orthecreedence
A modified version of John Resig's templating engine:
[http://blog.killtheradio.net/technology/a-small-
modification...](http://blog.killtheradio.net/technology/a-small-modification-
to-john-resigs-js-micro-templating-to-make-it-like-php/)

~~~
brokenparser
Implementing PHP syntax in JS is just ass-backwards, IMHO. Why not use
something simple like Mustache? I think it's a nice middle ground because it
lacks logic and runs in nearly any language. It's also used by the easiest JS
templating library ever, ICanHaz.js.

~~~
orthecreedence
Objection noted! Aside from the PHP opening/closing tags, the templating
system is the same as John Reigs and is fast, simple, and works extremely
well...so we haven't had a need to change. We've evaluated other options and
realized that switching won't really get us anything we don't already have.

Maybe once our team grows we'll re-evaluate again, since it's just two devs at
the moment.

------
programminggeek
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
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.

~~~
jbigelow76
I'd love to see an actual nuts and bolts implementation of the method you
describe. I've seen variations of it discussed in other threads but it's all
just theory. Deciding how to serve up pages based on user agent, scheduling
refreshes, etcetera. It all seems extremely complicated, I'd especially like
to know if the implementer viewed the ROI as worth it after the fact.

~~~
orthecreedence
Well, I've implemented it personally. Generally, here's what happens:

1\. A user loads the first page of the app. There is a small script
(index.php) that serves all front-end requests. It checks if the page being
loaded has already been scraped and if so, injects the content into the main
template, otherwise fires off a queued job to scrape that page and loads the
app regardless.

2\. The queue job forks out to phantomjs with the page URL, which listens on
the page for a "page-loaded" event, and upon a) this event being fired or b)
the scrape timing out, returns whatever HTML content in the main content area
(as well as any <head> tags) to the queue worker, which updates a database
table with url -> content mappings.

3\. The next time someone directly loads the page, that content is pulled and
injected.

4\. Scraped content expires after a certain amount of time. If expired content
is pulled out, it is put into the HTML for that page, and a queue item is
fired to re-scrape.

The obvious problem is that the page must be primed for content to show up,
which you can fix by a) either having lots of visitors :) or b) using/building
a simple crawler.

Also, when facebook scrapes our page to look for og: tags, we do the scrape
synchronously which takes longer, but ensures that the page's content is
always available. The same could be done for googlebot, but it's more
dangerous since rankings depend on page load speed.

As for our rankings, they are fairly high (it's the same as any app that
serves HTML directly would be since we are literally just serving delayed HTML
content).

So no, it's not just theory; we do it on Musio.com quite successfully. The
only user-agent logic we have is for the facebook scraper, refreshes are
scheduled by user action. The RIO is high because

1\. We already have a queuing system.

2\. Phantom JS is fairly standalone and our scraper is small and write once
then forget about it.

3\. We've found a good blend between simple and functional, with the deciding
factor being the delay.

~~~
jbigelow76
Thanks for taking the time to do a detailed write up, it's very enlightening.

    
    
        >So no, it's not just theory;
    

No offense was intended, I phrased my statement poorly. The technique is
usually discussed in more abstract terms would have been better.

~~~
orthecreedence
None taken! I understand you probably hadn't encountered anybody who had done
more than just toyed with the idea. I also agree, people like to talk about
how cool it might be, but I hadn't heard of anyone doing it in production
before us.

I think one of the reasons it isn't done a lot is because when people think
"one-page JS apps" it's usually account-based, making you log in to use the
app (at least the ones I use). So other than a few marketing pages which could
easily be handled by a CMS, there'd be no purpose to store generated HTML for
your own pages.

------
kaoD
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.

~~~
beermann
I was writing something to do this a while back actually. Just recently AirBnB
wrote about it as well: [http://nerds.airbnb.com/weve-launched-our-first-
nodejs-app-t...](http://nerds.airbnb.com/weve-launched-our-first-nodejs-app-
to-product). They're using Backbone on both the client and server to
accomplish what you're talking about. I haven't seen a complete framework that
does this yet though.

~~~
kaoD
I did something similar using Blade (<https://github.com/bminer/node-blade>)
which is a great client and server-side templating engine, but it wasn't as
smooth as I would've liked.

I guess we'll have to wait (or do-it-ourselves).

------
combataircraft
Both.

~~~
rozap
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.

~~~
kailuowang
Great point on the size of the team. It is definitely an important factor for
choosing a hybrid approach.

------
meaty
I'm not sure how we'd go client side efficiently. We have 2500 views!

~~~
shimms
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?

~~~
meaty
The latter. I'm not sure how you could transfer something of that complexity,
with all the UI logic efficiently.

------
edwinyzh
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
Use Yahoo Mojito. Same MVC code on both server and client.

------
papsosouid
>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
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).

~~~
coldtea
> _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)._

So basically you attack him only to agree with him? Nice.

> _Where they do provide benefit is to developers, for whom it makes creating
> rich interfaces absurdly easy._

No, it does not.

It makes creating rich interfaces a hodgepodge of immature and fragile client
side technologies.

