I'm sure Flash or Silverlight or other RIA people would argue that anything that's not a compiled native experience isn't as flexible or as fast as whatever they're peddling. Meh.
Yes, it's great to occasional dip into advanced client-side when that's needed. Just like Flash had its legitimate use cases here and there. But for the bulk of the UI interactions we're giving people, it's just not needed (or desired).
Either way, I'm very much looking forward to using the new version.
To me that's like how we in the past used Flash to play sounds in Campfire. Or reimplemented a poller in Erlang. Or use nodejs for the development Pow server. Use all the great tools available in the niches where it makes sense.
But the bulk of Basecamp is exactly the type of application that makes wonderful sense to do in Ruby and Rails. We've been sending down chunks of HTML in response to Ajax requests since we started doing these types of apps in 2005. So far I haven't seen anything to make me reconsider that approach for the majority cases.
Huge fan of your work. Been in love with Rails since the pre 1.0 days. Our team internally (we have an existing Rails 3 app that we want to improve rendering performance) has been going back and forth with "Rails should emit JSON and render client side" and "We should be smarter about caching and AJAX-ifying our pages".
Your post has given more ammunition to the Rails-only side, so that is really awesome; thanks for that!
There are reasonable arguments on both sides.
For Rails Improvement: * We know Rails * Scaling Rails is a solved problem * You can "just throw money at it"
For JS UI: * We know Javascript (http://www.github.com/toura/mulberry) * Why spend server $$ on boring HTML rendering? * We have better GUI test tools in the framework side (we can unit test our componentized JS GUI much easier than a mashed-together Rails ERB HTML) * We don't have that much money to throw at it, and that's wasteful besides
Presupposing, of course, that the server rendering JSON takes less time than stitching together ERB and the developer toolkit isn't any harder, would you find it more interesting?
Thanks,
-- Matt
I find the complexity needed in having MVCs on both client and server side to be the main problem. Especially since much of what applications like Basecamp are not all that heavy on the UI-interaction. A few bits are, like a calendar, so we use it there.
But obviously you can make it work either way. Just like Facebook manages to make PHP work. And some crazy kids still use Java. You should pick a development environment and style that fits your brain and your sensibilities. If you think client-side development is lovely, then by all means, go to town. Some people even think JavaScript is still as well as Ruby and that you don't even need CoffeeScript -- peace be with them.
Thanks for the reply. Look forward to using Basecamp NEXT (we use all the 37 signals products here) and seeing the evolution of your process as you continue.
-- Matt
DHH, I think you misunderstood here; I believe Jeremy's referring to the blog post where you said Basecamp Next had almost as many lines of CoffeeScript as lines of Ruby. I think that's where the 50/50 number came from.
I'm less curious about the performance here than I am about the maintainability. I saw a tweet where somebody said he'd done things the same way and encountered a maintenance nightmare -- he mentioned nested caching and pjax specifically -- but without context or detail, I'm taking that with a grain of salt. I think disregarding it completely would be a mistake too, though.
It's also kind of tautological that DHH is going to have a more pleasant experience developing in Rails than he is in other frameworks. ;-)
The maintainability story with pjax+caching is exactly the same as its always been with a Rails app. We just celebrated 8 years with Basecamp. That's a pretty good run.
You can write shit, unmaintainable code in anything, but to point at pjax and granular key-based caching schemes as somehow specifically prone to this? What? That doesn't make any sense to me.
We also had a swanky in-house client-side MVC framework cooking with Cinco. We used it once for Basecamp Mobile and while it was a good experience and the end result was great, it did little to sway my thinking on client-side MVC being a step forward in programming happiness (one of the key things I evaluate platforms by).
Again, it's perfectly fine to have a different opinion. I don't like the aesthetics nor the sensibilities of Python code much, but I certainly respect that people can make cool shit with it and even that they might enjoy the process.
The hoopla here is over the terribly flawed notion that client-side MVC is somehow The Future of web development and if you don't follow that pattern, you're living in The Past. Ha.
To take things to the extreme, if you chose to write Basecamp Next in pure x86 assembly (for speed, of course), I think we'd all agree that the code would be much more prone to maintainability problems. Similarly, it is plausible that choosing to write Basecamp Next entirely with pjax+backend MVC+granular key-based caching could be more prone to maintainability problems. Not that I have any particular reason to believe it will, but we're wondering if there are any particular reasons you believe it won't?
The granular caching scheme is similarly just a fragment caching setup using key-based expiration. Nothing new here, just that we used it to full effect.
So you're free to claim that writing Ruby on Rails applications are somehow inherently hard to maintain, but you'd be fighting against 8+ years of evidence to the contrary. Versus, you know, a very short amount of comparable evidence for JavaScript MVC applications based on current, recent frameworks.
I'd like to hear more about this, ideally in a blog post or two. I think a lot of people were waiting for Cinco's release, certainly I was, because we wanted to see what you'd do with it. The fact that you have Basecamp Next running without it certainly says something, but I'd be a lot more interested to find out what the specific tradeoffs were.
I think this is a key point and is one reason that server-side approaches will be relevant for a long time to come. Some applications, such as Gmail and Pivotal Tracker, feel a lot like desktop apps, and heavy use of client-side code is a necessity in these cases. But many—I'd argue the vast majority—of web applications produce a better user experience when they feel like ordinary web pages. I don't see that changing any time soon.
there's a lot you can do browser-side these days which would be insanely masochistic without client-side MVC, but that doesn't change the fact that lots of very useful apps run on the ordinary web pages model.
Neither flash, flex or silverlight are being pushed these days for these kind of services.
Like the new design and with that I don't mean so much how it looks but more how it looks like it's going to feel using it.
1. Controlling how long page render takes at the server is under the developer control.
2. The size of network load is under developer control.
3. Client side optimization are under developer control.
OP is saying 1 is low; 2 is low(not much difference between html load and json load); and 3 is low as there isn't much going on at client side.
Other than that:
1. User network is slow, hence leading to large load times.
Go bake potatoes - can't help.
2. User is located at a distant location from the server.
If the user is part of a market which the company sees as profitable, the server can be mirrored.
Or else you can go bake potatoes.
Keep up the hard work!
Rails was literally lifted out of Basecamp into a standalone framework that works great for CRUD-style apps. You might personally prefer another approach or think this design failed but Rails was definitely designed for this use case.
Ability to link to documents, bookmark, meaningfully use history and save pages to the disk for offline use. Ability of the users to customize standard behaviors without reverse-engineering your JavaScript code. Transparency, which often leads to much, much easier debugging and improved usability. No need to run a quad-core 4GB desktop to use the website.
And this is just the stuff relevant to internal (non-public) websites. You can argue that all of this can be achieved with JavaScript heavy clients, but in reality, it's just isn't. It's not something you get by default, it's tons of extra work, and most people don't do that work.
Even just in principle, it can't possibly be close to as fast (client-side can render optimistically, where possible), and it can't be close to as flexible (you don't have a model of state on the client to perform logic with).
In principle, server-side rendering can allow you to share pre-rendered components between thousands of users saving everyone tons of work. In practice, rendering on the server side is just string concatenation and is insignificant compared to things like running SQL quires, which you'll have to do anyway.
You can manipulate the page url/browser history from js, and you can use the url to set the application state. History and bookmarks work perfectly well in gmail, for example.
This does take explicit coding. But, if fragments of the page are being replaced as bcx does, then you need to do similar coding anyhow. Otherwise, you're doing whole page loads on every request.
js works pretty well on modest smartphones, at which level network latency is usually the major concern...
It should not be similar. There is a huge architectural difference between the two approaches. In server-side approach you're adding caching or prefetch to an already working application that has established and working URLs. With client-side approach, you need to implement adapters that transform URL information into the client state that is normally achieved by a series of UI operations and AJAX calls. Then you need to add new code to generate URLs and manipulate history.
The beauty of caching or partial page fetches is that they are generic. History manipulation is not.
js works pretty well on modest smartphones, at which level network latency is usually the major concern...
The last time I tried to browse on Kindle, it choked and died on most JS heavy websites. When 500MHz processor is not fast enough to browse the web, to me, that's a problem.
But returning a cached html fragment is the exact same amount of work on the server as returning a cached-json value. Plus, it's less work for the client to drop the already-rendered html into a container than to have to bind the model to the template.
I feel like I'm being super dumb, but to me this approach is going to result in faster rendering.
curl -sIX HEAD -o /dev/null -w "%{time_total} s\n" https://asset1.basecamphq.com/rev_7ab3626/images/indicator.gif
gives me about 600 ms min. which is quite high compared to e.g. https://encrypted.google.com/textinputassistant/tia.png (45 ms min.)Ping to 37s (204.62.114.1) is only about 109 ms, so it looks like the SSL handshake is very slow?
But I know the latest OpenSSL does have an AES implementation that uses AES-NI when those instructions are supported.
It still needs to go back to the server to fetch new data. And it's not like rendering on the client side is instant and free. There are plenty of JS-heavy websites that visibly lag during UI operations because of all the stuff that goes on during "rendering" (in quotes, because it usually includes large chunks of business logic).
http://jsperf.com/dom-vs-innerhtml-based-templating/350
If you want to use a decent library, you can rest assured that your client-side templates will render far faster than the Ruby version of the same HTML.
I realize that ruby is significantly slower than v8/JägerMonkey/Tracemonkey/etc, but is it so easy to discount the significant disparity between the average compute power of a server vs mobile/laptop?
I think a stronger counter argument would be flexibility, smaller http responses (and thus less latency), and possibly an argument that it is simpler or more straightfoward, in favor of client-side javascript templating/rendering, but rendering speed? Not so sure.
Additionally, if you are doing small updates the DOM API is faster than injecting .innerHTML. I think this has changed in recent years and .innerHTML might have caught up for larger nodes. I personally still use the DOM API because it encourages more simplistic layouts.
When the server renders the html, it has to send all the portions of the view that have changed. When rendering client-side, the server only needs to send the portion of the state that changed.
It can, but maybe there is a way to write Basecamp so that large changes in view are rare.
On the flip side, you have to congratulate them on what seems like really great results. I'm definitely in favor of doing what works and what you're comfortable with. I just don't think Basecamp Next Next will be written this way.
IME, there isn't a smoother way to implement a bunch of RESTish json endpoints hooked up to a database (resources) and have dependency management and compilation for your frontend js/css (via the asset pipeline).
There may be other frameworks out there that make serving up and delivering client-side driven apps easy, but I haven't heard of them.
Personally that's why i like this whole shift to single page apps. Just as we've decoupled certain aspects of the server-side development, we can do the same with the UI.
Maybe you are right. However it it too early to do a big rewrite in JS. There are many JS frameworks but no clear leader. I am sure that in 3 years decision how to design you client side web app will be much easier.
Sure.
1) Client side UI frameworks are still immature. For example Backbone is minimal, while Ember is more featured but with bad documentation and not proven yet. Big frameworks with UI widgets never caught on and are too restrictive. GWT is also on the down and out, etc...
2) Same goes for the tools you need for debugging, unit testing, automation, etc. Nowhere as complete as the server side tools that have been honed for 10+ years.
3) Client experience can be extremely different, when JS performance differs widely between Firefox, Chrome, Safari and IE versions. Not to mention not everybody supporting the history state API.
4) JS performance for long running pages can also vary, due to memory management.
and it can't be close to as flexible (you don't have a model of state on the client to perform logic with)
And on the client you don't have a model of the server (where the actual data are and where the actual actions are performed) to perform logic with.
Developer happiness aside -- there are plenty of folks who like JavaScript just as much as Ruby -- and assuming that we're talking about an non-public-facing app (like Basecamp Next), is there still an argument that can be made in favor of doing your UI on the server side?
Even just in principle, it can't possibly be close to as fast (client-side can render optimistically, where possible), and it can't be close to as flexible (you don't have a model of state on the client to perform logic with).
I think that the truth of this is already admitted in that the really fancy bits of UI are being implemented in JS: http://37signals.com/svn/posts/3094-code-statistics-for-base...