Server-side view or client-side MVC? (kailuowang.blogspot.com)
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
[ 2.7 ms ] story [ 142 ms ] threadWhen 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.
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
Maybe I'm just splitting hairs, in general I agree with the author's premise.
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 :-)
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.
https://plus.google.com/app/basic/stream/z123j3wxwrm5jb0tv23...
Source: Comparison of various pages: http://mike.teczno.com/notes/bandwidth.html
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).
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.
I've written several client side javascript apps, although obviously I'm not dumb enough to actually write them in javascript when there's so many "tolerable language -> javascript" compilers available.
>Yes, strictly speaking, there's nothing inherent to client-side JS MVC frameworks that creates a better experience for end-users
I didn't say anything like that. I said 90% of people writing client side javascript interfaces are doing so for no user benefit, just following a fad. There's plenty of cases where an interface is better in javascript, unfortunately that's only ~10% of the cases people are using javascript for.
>Where they do provide benefit is to developers, for whom it makes creating rich interfaces absurdly easy.
Compared to using horrible shit like ruby on rails perhaps, but compared to decent tools using a javascript framework is a significant step backwards. That's one of the reasons we only do it when it helps the user, rather than all the time just to make our stuff worse.
>But hey, don't let me keep you from thinking whatever keeps you inside your comfort zone
You really need to make the effort to read what you reply to. If you just want to make up nonsense to respond to, that's what blogs are for.
Or are you saying that it isn't possible to efficiently manage 2500 views using a client side framework?
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.
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.
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.
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?
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.
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.
Here's a short primer: http://www.gethifi.com/blog/javascript-templates-and-how-we-...
There are various libraries you can use to make this easier for yourself. Underscore and handlebars are too good options.
Edit: JS -> CoffeeScript.
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?
Maybe once our team grows we'll re-evaluate again, since it's just two devs at the moment.
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.
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.
I guess we'll have to wait (or do-it-ourselves).
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.
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.
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.
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.
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).