JavaScript Has Its Place, But Not Every Place

No javascript

JavaScript is everywhere these days; more-so because legions of developers play follow technology leaders like the Pied Piper playing his flute. 

I’ve worked on many Rails projects over the years and the inevitable pain points usually turn out to be JavaScript. Whether it be mounds of jQuery selects, poor attempts at AJAX everywhere or lately, Backbone.js and some other MVC frameworks which virtually mirror much of the backend in the UI. Unless these technologies are implemented to perfection, it leaves evidence of attempts at “playing” with a new framework with artifacts left behind that last a lifetime.

Some issues I have with using large amounts JavaScript in your Rails (or any web framework for that matter):

  • Leads to lots of code in the browser – with tons of JavaScript, applications start to get slower. There’s only so much client-side code a brewer can expect to handle.
  • Leads to lots of code inherited that is hard to debug, hard to support and the client ultimately pays – this is probably my biggest pet peeve. It seems like every Rails project, there’s a different JavaScript framework used and it’s the first time the developer is using it. 
  • The examples of bad code are numerous and hard to fix. It is really hard to understand the intent and really hard to both support and enhance. In the end, the client pays the price from both a monetary perspective and a maintenance one.
  • Developers like to “play” with the new hotness leaving breadcrumbs of learning something new of a framework that gets dropped or at least minimally maintained.

I came across a great article published recently from the developers of Charm. One of the developers, Thomas Fuchs, who is previous Rails core member and a well-known member of the JavaScript community gives his thoughts on the heavy use of JavaScript in a web project.

Hi Sasmito, as for technical issues, we where plagued by various problems that are not related.

The app as it is, is using Backbone.js, Underscore.js and Zepto on the front-end, and Rails 2.3, Postgres, memcached, redis, resque, and for websockets Sinatra, and a few other things. The front-end is communicating with the back-end via a JSON API.

I’ve come to the realization that this much client-side processing and decoupling is detrimental to both the speed of development, and application performance (a ton of JavaScript has to be loaded and evaluated each time you fire up the app). It’s better to let the server handle HTML rendering and minimize the use of JavaScript on the client. You can still have fast and highly interactive applications, as the new Basecamp shows—letting the server handle most stuff doesn’t mean that you have to cut back on cool front-end features and user friendliness.

I’d argue that all these newfangled libraries are actually detrimental to the user experience in some ways, as they lock you into certain patterns (it’s hard do to things the authors didn’t anticipate) and if you use something like Ember (which we didn’t), it’s even worse as all applications using it practically look the same.

We’ve spend a lot of time getting Backbone to work properly, as the easy-of-use quickly deteriorates when your models get more complex. It’s a great choice for simple stuff, but email is far from simple. We also had to add yet an other extra layer of processing to generate “ViewModels” on the server because the normal Rails serialization of objects wouldn’t cut it.

What you end up with is building a layer cake that doesn’t add any value and slows down development. Especially when you’re starting out and need to stay flexible you don’t want to have too much code around—and Rails is great for that. But… adding a JSON API layer and basically a second application that runs on the client is annihilating this advantage for you.

All in all, my current recommendation for SaaS-type web apps is: Rails 2.3 (or Rails 3.2 if you prefer), a Postgres database, as much HTML generation on the server as possible and augment that with RJS (Rails’ mechanism to push JavaScript snippets to the client that get eval’d). This allows for direct re-use of server-side templates, and it’s simple, and works well. As an added bonus, keeping things on the server allow for much better error and performance monitoring and thus quicker turnaround for fixes. There’s also a lot of great stuff in this direction coming up in Rails 4 (like Turbolinks).

Alas, keep it simple and don’t repeat yourself.

This is some of the most common sense advice I have read in a very long time.  Please read the comment and consider the advice before harsh comments here.  I know there are a lot of JavaScript developers out there but I ask those to use it with care.

A wise man once said, “Just because you can, doesn’t mean you should”.  No idea who said it but words to live by.  This applies to so many things, especially JavaScript.

There are so many new frameworks popping up each day. We don’t need more frameworks, we need better ways to use them; such as standard and proven usage patterns, well-known interfaces and published best-practices.  It’s like the wild-west out there in JavaScript land and things are not better because of it.  

You are not doing anyone any favors using all of this JavaScript.  Use it sparingly, use it right and remember that JavaScript is not a silver bullet.

  • http://twitter.com/DanielStocker Dan Stocker

    I’d like to start out by admitting that there _are_ serious problems with the _use_ of JS today. Most developers don’t know how to approach building complex web applications and end up with (and in) a big mess. But to blame the variety of frameworks for this, and say we don’t need more? We do need more, because clearly, the one that is to standardize front-end development has not arrived yet!

    There’s an answer to all issues raised in this article. Browser can’t handle your scripts? Manage them. Load only what’s necessary. Wipe out what is not. Layer-cake? Well, complex requirements require complex solutions. Layers manage complexity. Try writing a web app with complex windows, views, and popups with HTML rendered by the backend. Libs locking the dev in to certain patterns? While this *can* backfire, that’s pretty much the idea. JavaScript offers way too much freedom for any pattern to arise and stay consistent across a large app by itself. And so on.

    Fuchs’ recommendation may be applicable to simple apps with limited feature sets, but surely not to complex web applications, hint: Facebook. I agree with using JS ‘right’. But the rest seems to be no more than running away from the problem and back to the warmth and safety of practices we already know, only to delay their inevitable failure.

  • http://www.accidentaltechnologist.com Rob Bazinet

    Hi Dan,

    I agree with that most developers don’t know how to approach building complex web apps. This is the problem I see and face daily, but how to fix. I don’t think more JavaScript it the answer either until there is a better way to use it. The code I see is from the land of cowboys and that is just not good, both from the perspective of the poor developer that gets handed the project next and the client who has to pay dearly for the developer to make sense out of senseless.

    I like Thomas’ idea, from hard experience, of use JS carefully and in the right places. It’s easy to go wild with JS and make the entire front end JS..*if* you know what you are doing.

    I don’t claim to have an answer but it would be nice to agree there’s a problem and address it now. I don’t see the landscape of JS getting better, only worse for those of us writing app in Rails, Django or ASP.NET MVC..it’s all the same and JS used wrong just makes apps really hard to maintain.

    Your point about complex web UI’s is noted and a well-written Backbone.js app is a thing of beauty, but really hard to do well when a developer is trying to do it all. The application is going to suffer. Sure, there are developers out there who can do it all but those are a rare bread and too many average or below and create chaos for the next developer to take over a project. Trust me, I inherited one of these recently.

    I hope of a day with better JS, maybe of the unobtrusive style. It might only be a dream but something has to give.

    Thanks for taking the time to comment.

  • http://twitter.com/DanielStocker Dan Stocker

    Hi Rob,
    Perhaps working for clients – as opposed to working on products puts you at a disadvantage here. Taken this post as a plea to those touching a project before you – I can see why you’d feel more comfortable working with an ‘older’ mix of technologies. I’m a product guy, so I tend to see things from that perspective.

  • http://www.accidentaltechnologist.com Rob Bazinet

    Understood. I think for a product person it’s a bit different. If you choose a technology such as Backbone.js you can build on it, get better, refactor and repeat.

    Working for clients is a bit different since we inherit whatever choices the last developer or developers made and often times those are hard to live with. I think it often gets derived from whatever the hot JS technology was at the time, it was used poorly and when the developer moved on, it’s now technical debt that is hard to repay.

    I see this in RJS templates, AJAX-ified everything and I bet a couple years from now, really bad usage of Backbone.js and others. It’s sad really and I wish for better.

  • http://mattbriggs.net Matt Briggs

    You have done a great job talking about the effects of using javascript poorly in a webapp, can’t agree with your solution to use it as little as possible.

    I would recommend checking out ember.js. It seems like what you are looking for is a super heavy framework that makes good decisions for most webapps (aka rails style). Ember is that.

    Also, turbolinks is a terrible idea, and reading thomas fuchs talk about it like that made me a little bit sad.

  • http://www.accidentaltechnologist.com Rob Bazinet

    Hi Matt,

    I will give Ember.js a look, I know there is some recent Peepcode episodes with Tom Dale and Yehuda Katz cover ember.js and using it with Rails. The most recent one is – https://peepcode.com/products/emberjs.

    Why do you feel turbolinks is a bad idea? I know the Rails core team embrace it and that came from the internal work at 37signals. I can’t yet say it’s good or bad, but to me the idea of it is good.

    Thanks for the comment.

  • http://mattbriggs.net Matt Briggs

    I liked the bit that wycats (core member of rails, jquery, and ember) wrote about it https://plus.google.com/106300407679257154689/posts/A65agXRynUn

    My biggest issue is the messaging. Turbolinks is not fairydust that you sprinkle on things to magically make them faster. It is a very specific technique that is very useful if you know when and how to use it.

  • Dennis

    I feel the main problem is the people hired to create complex, javascript apps don’t have the experience to tackle projects at that scale.

    My last two projects demonstrate this perfectly. The first was created by a team of former C# / Java / C++ app developers who had never created a javascript app but had tons of experience in creating complex apps. The entire cycle was fairly painless and the product is a thing of beauty. My current project is staffed entirely by PHP/Javascript guys who have years of experience in Javascript but are completely inexperienced in large app development. We’re six months in and every day is sheer torture – nothing works and it’s a constant struggle to communicate basic patterns and concepts to anyone on the team.

    I am the team lead on both projects and the architecture/framework are identical (although I arrived late in both cases and did not get to choose my team members). At least when you hire someone who has created a complex app in the past (regardless of language), there is something of a guarantee that they can do so again. In my mind, the frameworks out there are all pretty decent (although Backbone is getting really long in the tooth and needs lots of extra plugins to be acceptable / usable).

  • http://www.accidentaltechnologist.com Rob Bazinet

    I think not using a technology like this as an answer to everything is exactly one of my points. This is how developers use JavaScript today, like it’s magic.

    I’m not sure how to stop developers from doing this but this is what causes much of the issues I see today.

  • http://www.accidentaltechnologist.com Rob Bazinet

    Thank you for the reply Dennis. I think you are seeing *exactly* what I am talking about and deal with most days when inheriting a project.

    I run my own company and take on client projects, some green field and some not. The ones that have been around for a while almost always suffer from some form of this. I can usually point to the problems as being JavaScript related, so many different frameworks and so many developer wanting to give them a try. A try isn’t good enough and leaves a mess.

    Frameworks are pretty decent but history repeats itself; frameworks get developed, used and then recede into the night. I see Backbone.js having the same future.

    Your experience is a perfect example of what I am talking about.

  • Mr Spoon

    The logo that you’ve used in your “Say no to Javascript” picture is the Java logo – not Javascript

  • http://www.accidentaltechnologist.com Rob Bazinet

    I know. I just thought it was cool.

  • Pingback: Share Point |()

  • http://twitter.com/JosephHurtado Joseph Hurtado

    Rob,

    I have to agree with your main points. Until we get a new generation of JS frameworks, it is best to simplify as much as possible and do more on the server.

    Ember.js may be this new generation, but still the mantra of less complexity is better for your code will always held true. Perhaps the answer is going with one single stack in the server and front-end. Would a combination of JS in both places work? We will know eventually.

    As of know using the best most solid back-end and some good solid JS seems to be the best.

    Cheers,

    Joseph Hurtado
    Founder Agile Lion Institute
    Web: http://www.AgileLion.com
    Twitter: @AgileLionInst, @JosephHurtado

  • http://www.accidentaltechnologist.com Rob Bazinet

    Hi Joseph,

    Good to hear from you and stopping by. :-)

    Ember.js may be the new generation, time will tell. I just think most of these frameworks are trying so hard that the developers make the implementation details of their use so hard that maintenance is difficult. I think most about the next developer who comes along and has to try to figure out an archaic old framework.

    I have a project right now that is total mess and it is from the days when people thought it was a fantastic idea to use RJS templates all over the place with AJAX calls sprinkled in. The app works, but trying to debug and enhance…the apps seems magical.

    Don’t get me started on node.js…it will be a cold day in hell when I use JavaScript on the server. Not going to happen. It sucks in the browser, it will really suck on the server.

    I guess if you use Ember.js, Backbone.js, Knockout.js or one of the others like it you can have a nice application as long as the developer has a clue what he is doing and doesn’t take their learning and put it into production.

    My 2 cents.

  • Pingback: 向 JavaScript 说“不” | HTML5工作室()

  • Jeff Pritchard

    I knew Ember was the wrong tool for the job…I just thought it was cool. ;)
    (sorry, that was mean. This is a VERY interesting topic. Thanks for starting it!)

  • Pingback: 向 JavaScript 说“不”()

  • Thomas

    I recently completed an entirely restful web application for the university I work at that uses quite a bit of Javascript and communicates with the server using JSON. By defining a very clear specification for the client-server communication, and having the entire view generated client-side I find debugging and maintanence extremely easy. I could completely swap out the UI without touching the server-side.
    The client-side code is designed to have very clear flow and doesn’t use any framework. There ended up being about 1500 lines of Javascript, with 100 lines per source file. A quick glance through the files and I think anyone would see how they are organized and work together, and where to add new code or make fixes. I haven’t used RoR, but RJS sounds like a terrible idea to me. I find the issue with Javascript is people start writing it in “snippets”, rather than structuring it properly, until its a 500 line tangled mess. RJS sounds like it promotes not only that, but the generation or mixing (?) of your Javascript with your Ruby.
    The application I developed was to take the place of a desktop application, and I feel like the users would have found the app to clunky compared to a desktop application if I built it to query the server for every view change. Feedback has been really positive, though currently it only has a few hundred users…
    Honestly, since I graduated university I haven’t really worked under anyone with experience and have had to take a lot of leadership roles (something I’m not sure I’m qualified for). So that makes me constantly question whether I taking the right route in solving issues. Do you think the sort of decoupling of client and server I described, and the meticulous structuring of client-side javascript, if done properly (who knows if my code would qualify), would offset some of your apprehension towards client-side DOM generation?