The Web Platform has gone a long way since HTML5 was first made popular and people started looking into JavaScript as a language that could do build complex apps. Many APIs have emerged and there is an abundance of content out there about how the browser can leverage all this.
This specific article series will go a step further and focus on how these powerful technologies can be leveraged in practise, not to building cool demos and prototypes, but how real practitioners use them in the trenches. In this (post)HTML5 series, we'll go beyond buzzwords and get practical insight from experts about what has actually worked for them. We'll also talk about technologies (like AngularJS) that go a step further, and define the future of how the standards and web development will evolve.
This InfoQ article is part of the series “Next Generation HTML5 and JavaScript”. You can subscribe to receive notifications via RSS.
As more and more logic ends up being executed in the browser, JavaScript front-end codebases grow larger and more difficult to maintain. As a way to solve this issue developers have been turning to MVC frameworks, which promise increased productivity and maintainable code.
Back in 2013 InfoQ had asked the community to rank JavaScript MVC frameworks according to the features they had, and how mature they were:
Now InfoQ asked the opinion of expert practitioners about how they use these frameworks and the best practices they follow when developing JavaScript applications.
InfoQ: What is your favorite JavaScript MVC framework, how long have you been using it, and what is the fundamental problem that it helps you with?
Matteo Pagliazzi: Angular is actually the framework of the moment, and it's not only a matter of GitHub stars: it has the biggest number of libraries, modules… and it's being talked (and used) by a lot of developers. It's obvious that we (devs) like it. This is, I think, because it's very easy to get started with: it takes 5 minutes to have something even not trivial working but at the same time it's very powerful. So the learning curve gets steep as you move from the basic things to the core of the framework when you find out it's very complex.
Julien Knebel: I've been developing with Ember.js for more than 2 years now on 5 production web apps. I'd say that it gave me flexibility, speed and confidence so I could focus more on shaping the whole user experience instead of investing huge amount of time in complexe features, like a robust asynchronous router for instance.
Brad Dunbar: My favorite is Backbone. It provides simplicity and flexibility that others don't. Also, perhaps more importantly, it's code is generally simple and readable.
John Munsch: My favorite framework is AngularJS, I've been using it just over a year, and the honeymoon is not over yet.
The fundamental problem I look for any front-end framework to solve is to give me something with sufficient bones, muscle, and connective tissue to help me build a complex UI on the front-end not just comparable to, but better than, what we could build with a request/response back-end framework like JSP, PHP, Rails, etc. in the past.
Julio Cesar Ody: I mostly use Backbone, and increasingly React.js has replaced Backbone views for me.
All web applications I build run fully in the browser, and communicate with a server using an API and/or WebSockets. This means a lot of logic ends up being written in JavaScript, so Backbone helps me keeping things orderly and maintainable.
Thomas Davis: My first experience with formalized JavaScript MVC’s was late 2010 and at the time I was deciding upon using Backbone.js and Sproutcore. I made a comparison post which reached the front page of Hacker News and received over 100,000 views. Based off the feedback at the time I decided to use Backbone.js because it was minimal and didn’t stop me from implementing complex functionality without being confined the the conventions of a larger framework. As I learnt Backbone.js, I wrote tutorials to give myself a more concrete understanding of the framework. These posts have received millions of views and still do. The current archives are at backbonetutorials.com.
When building a product these days, the user experience and design is as crucial as the necessity of keeping the site up. Single page applications allow you to make user experiences which traditional pages cannot match due to page reloading. For example, imagine using Facebook where every like and every comment made you refresh the page.
InfoQ: With many alternatives available, how does the framework you use compare to the rest of them?
Julien Knebel: It performs really well! I never imagined it'll let me code entire apps almost all by myself. Angular is also really good though, I really like how fast you can get up and running with it, however I believe it tends to become more and more tedious as your codebase grows. On the other hand, I had more difficulties at the beginning with Ember but they started to melt like snow in the sun after a couple of "ahah!" moments while learning it. Another important point (at least for me) is "componentization", I disliked how Angular Directives deals with this and Ember Components really feel like the right way of doing it.
Brad Dunbar: I find that it's very rare that a javascript library can precisely fill all the needs of my application. This means that I often end up writing around them. Backbone's functionality is small and provides utilities that I can compose instead of larger pieces that aren't exactly what I need.
John Munsch: That's a tough one, my experience only stretches to Backbone.js (just under two years experience) and AngularJS (just over a year). But between those two I don't think it's a tough choice at all.
Backbone.js was OK, but we had a large project with as many as half a dozen people working on it at its peak and the problem we got into was with all of the large gaps in Backbone.js that you typically fill with other software (two-way binding, validation, templating, AMD, etc.). If you don't figure out your solutions for all of those gaps before you start every developer in the group ends up filling it his or her own way. If you're under a time crunch and writing really fast, it can be really difficult to catch all of the divergence and enforce much consistency.
We ended up with a working project at the end and it was way faster than their old solution but it was a Chimera; every part of it appeared to be a different animal. With AngularJS a lot more of those parts are part of the framework itself and there's less room for that kind of problem.
Julio Cesar Ody: I'd say Backbone is the most minimal, but that's not a particularly useful point to focus on. Reason being ultimately what one resonates with the most, and in a way, the one that you're happier working with, is also the one you're going to be most productive with.
So between Backbone, Angular, and Ember, you can't go wrong. I'm leaving React.js out since it's really just a UI components library, so it shouldn't be confused with an applications framework.
Thomas Davis: A lot has changed since 2010 and even though I am always trying to break out of my old habits, I still use Backbone.js at the moment. It has remained minimal and hasn’t changed any of its core beliefs or methods. Though in my opinion it definitely is on the verge of being superseded by the competition. Efforts made by libraries such as Angular to give developers more intuitive control over the DOM make Backbone.js seem archaic when it comes to rendering. With the new modular JavaScript movement it is also possible to call Backbone.js monolithic in size. There isn’t any reason why Models, Collections, Routers and Views should be packaged together into one library, alternatives such as Components.js are writing those parts as individual modules. This hasn’t actually been done fully at the moment and I’m considering it one of my next projects.
InfoQ: Building faster, more robust front-ends is nice, but what about performance? Especially on mobile. What is your experience?
Igor Minar: I think mobile is still under-served area for web development. A lot more focus needs to be placed here and Angular is definitely refocusing on mobile in its 2.0 version.
Julien Knebel: Ember is heavier than others, it's a fact. Even if you minify/gzip it, so this is something important to consider especially if you plan to build mobile web apps. Then dealing with smooth 60 FPS transitions is tough, either you implement them with Ember or another one. I'd say that you need to know how to deal with common rendering performance issues, otherwise you'll get in trouble no matter what framework you chose.
Brad Dunbar: Backbone is rather performant and small compared to others. I haven't had any issues using it for mobile, though I usually don't write for devices more than one generation old.
John Munsch: We haven't really focused on mobile yet for my current site, but we definitely did at my previous employer. Because they needed to run an additional web interface on barcode guns in warehouses and hangars we crafted a secondary UI which was a handful of pages built just for the guns. They used the same technology as the desktop browser UI and the pages called the same back-end API but the pages were smaller and simpler for the small touch screens on the guns.
In that environment it seemed a better solution than trying to make a responsive version of existing pages which would need to drop off 80% of their functionality on mobile. Note: We were very lucky that good quality barcode guns with HTML5 browsers became available before the project was due to ship. Early work was done with guns that only had IE 5.5 available. *shudder*
If I were to return to this project today, the first thing I would probably do is add Grunt for concatenation, minification, and revisioning of the JavaScript to speed the mobile and desktop up further and turn on expires headers so browser caching could be turned up to a month or more.
Julio Cesar Ody: JavaScript is fast, browsers are pretty damn efficient these days and increasingly becoming more so. It does take some serious messing up for things to end up really slow.
That said, performance is everything when it comes to good UX. But the JavaScript side of things is just one part of that. How you use CSS (and transitions, animations), how good and thin the markup is, all that also has a big impact on performance. You need to be mindful about the whole.
If any of you did any micro-controller programming in C perhaps, you know what it means writing programs that run on constrained devices. Although phones are rather powerful computers, they're still significantly slower than the average laptop. You can't afford to make as many mistakes, and you need to take the rule I mentioned before and be twice as careful.
Measuring things that are problematic helps a lot. Chrome DevTools comes to mind.
Thomas Davis: There is no silver bullet for choosing a front end development approach between mobile and desktop at the moment. Sometimes native apps are better, sometimes JavaScript apps and sometimes server generated pages. Though for performance questions related to the DOM in general, I’d probably make a safe bet on React paving the way. React implements a virtual DOM that diffs the browsers DOM and only makes changes when necessary for high performance rendering. Because it’s a virtual DOM, you can also render DOM’s on the server and access them programmatically.
InfoQ: What is your typical workflow using your framework of choice? What tools do you use to develop and debug?
Igor Minar: Webstorm, Karma, Chrome.
Julien Knebel: I use Grunt as my build tool to preprocess, precompile, postprocess, concatenate, minify, etc. Then TextMate2 is my IDE of choice for years. I also spend a huge amount of time in Chrome dev tools debugging with breakpoints and debuggers. And of course I couldn't live without Git.
Brad Dunbar: I tend to use a somewhat minimalist setup including a CLI and vim/node/npm. Lately, I've enjoyed using browserify for bundling. As for workflow, I do the typical code, refresh, debug cycle. I've never been a huge proponent of test-first or anything of that nature.
John Munsch: Most of the developers on the front-end team use WebStorm or Sublime on Macs, the project as a whole is built and run via Maven because the back-end is Java, and we recently started running Grunt from within our Maven builds to get optimizations on front-end code. Jenkins is used to build, run unit tests, and deploy to various testing environments and production.
Local developers run Karma in the background to run the AngularJS unit tests we have today (sadly only 30% code coverage today).
Julio Cesar Ody: I do as much of the design as I can (when I'm the one doing it) upfront. Looking at how the page will look like helps me do a mental breakdown of the components I'll need to write.
I've used Hopla, which I've written myself, a lot in the recent past, as a build tool. It uses Sprockets for transpiling CoffeeScript and SASS, and compiles the application to static HTML/CSS/JS. This comes in handy for deployments, and for building Phonegap apps even.
Then I start implementing a design usually by writing a static HTML page with styles using SCSS, going through each part of it later and replacing with JavaScript components.
Thomas Davis: Honestly I’m pretty indifferent to how people like to develop and debug, and my methodologies change on a per project basis. Though the only advice I dogmatically give is that developers use Asynchronous Module Definitions (AMD). Require.js gives a rock solid implementation of AMD and in my experience makes debugging the easiest of all languages and environments. Not only does it help you structure your code intelligently but also makes the barrier to entry of your code base very low because everything has to be a dependency referenced by a file path.
InfoQ: As applications grow bigger, it can be a challenge to keep a robust architecture and maintain a large code base. How does your favourite JavaScript framework scale? Also how does it scale as development teams become bigger and different people need to work on different parts of the functionality?
Igor Minar: Code reuse, reduction of boilerplate and style guide and conventions are important for reducing complexity of large code-bases. But in our real world experience we've seen that high quality test-suites have even higher impact because they allow for major refactoring while keeping the risk low. And refactoring is a key to keeping the code base clean.
Matteo Pagliazzi: Besides the complexity (like the presence of Services, Factories and Providers which is very confusing), with simplicity a goal of v2 (http://blog.angularjs.org/2014/03/angular-20.html) what I personally don't like is the dirty-checking mechanism used by Angular to see which properties have changed and update the view according (but also this is going away as Object.observe is implemented natively, allowing for notifications to be issued upon change - instead of having to check for every property's changes)
To wrap up: Angular is really great, backed by an awesome community, an enormeous number of external libraries that usually satisfy every need and even in case you didn't find what you need you can always write your own directive. But it is also full of complex concepts that take time to understand.
Julien Knebel: Ember deals really well with growing codebases because of its "enforced good practices" and its strong conventions which let you do a lot with single lines of code (aka convention over configuration). It helps each member of the team debug other's code faster. I saw some developers getting angry because they felt constrained to code how Ember wanted them to code, but I guess the real frustration came from the fact that you first have to understand/learn Ember before trying to do fancy stuff with it. And I do believe that this extra education time really worth it in the long-term. Plus, I tend to trust Yehuda Katz and Tom Dale's work a lot (but this is not really objective I guess :)
Brad Dunbar: I think large JavaScript codebases are challenging regardless of the framework used. It comes down to the team maintaining a set of guidelines and sticking to them. Use of modules of some kind (I mentioned I like npm and browserify) helps tremendously though.
John Munsch: So far our experiences with scaling are good, front-end JS scales well because there's lots of static files amenable to optimization, caching, and even CDNs. Pretty much the only bad experiences have been with trying to render thousands of items worth of data on pages. We've tried to be encourage the use of pagination and other workarounds but we can't always get agreement to use them and large chunks of data generating thousands of DOM elements is a recipe for problems on old browsers.
Other problems have actually completely gone away. For example, AngularJS's default behavior of discarding views and controllers when switching between views keeps memory usage on another view from impacting the present view. That's a simple solution that helps developers avoid a lot of problems as they add more and more functionality to a single page app.
Julio Cesar Ody: I don't think any of the popular frameworks has a defined scaling path. It's up to the developer to think of something sane and run with it.
I've always liked the concept of components/modules. It lets me think of writing programs much like building a watch. Each part (or component) has its purpose, and needs to work as independently as possible, exposing a small surface area that other components can interact with.
Thomas Davis: As I said above as long as you use a modular JavaScript framework such as Require.js, scaling and maintaining your code base is a walk in the park and will only depend on your coding practises. Though Backbone.js does need to be split into its own modules at this point so instead of requiring Backbone as a dependency, you would only require Backbone.Model for example.
InfoQ: For teams that are just now considering adopting a JavaScript framework, what would be some of the common pitfalls to worry about?
Matteo Pagliazzi: Working on a big open source project that uses Angular as the client side framework I found that for developers without much experience it's easy to incur in problems with inheritance or to start polluting the $scope and $rootScope with a lot of objects that at a certain point will start to slow the application and grow the RAM used by the browser (we easily use 300+ MB and it can easily get to 1GB with an even small memory leak). The fact that it's made data binding so "simple" is of course fantastic but you have to understand that it will always work as you want just because it's "magic".
Julien Knebel: All those MV* frameworks are heavy JavaScript calculations on the front-end, therefore if your app needs to print a large amount of data to the user you'll quickly hit your performance budget (talking about the 60 FPS budget). You'll have to deal with pagination, intelligent scrolling, wisely dosed CSS decorations, subtle sequencing, couple chosen places to display spinners to let network calls retreive data, etc. Eventually, all that stuff will matter a lot.
Brad Dunbar: I think the most common issues come before you've even dug into the framework. Your client needs tests, modules, a package manager, and continuous integration just like server. If you can stay true to those, you'll probably be alright.
John Munsch: I've mentioned the problems we had with Backbone.js, but there are some common things that can always come up. For example SEO is a factor for pages generated entirely via JavaScript on the front-end. I've been fortunate that most of my work has been SaaS so SEO hasn't been anything we've cared much about, but if you're building something for the wider web you need to look at solutions like Prerender.io, BromBone, etc. to see how you're going to deal with that. Google Analytics can present similar problems. None of these are unsolvable, but it's good to go in knowing that there are some issues and you may need to pick a solution.
For us, without a doubt, IE8 has been one of our biggest problems. It's the last browser with a significant chunk of market share out there which does not have a built in JavaScript just-in-time compiler. As a result, JavaScript heavy front-ends can be slow at times, can trigger "unresponsive script" errors when displaying lots of data, etc. The sooner the Lovecraftian horror that is IE8 goes away, the better for all of us.
Julio Cesar Ody: The learning curve is definitely the biggest problem I see. Most people have been developing web apps for years, which consist of a server component sending taking, processing requests, and sending HTML back to the browser.
This is a completely different paradigm which resembles network programming (client/server) a lot, and that's not something many have done before. It has many of the same problems network programming has, and having a background in it surely helps.
Thomas Davis: The only major pitfall to really worry about is not having server generated content available at the url. This of course stops search engines from being able to directorize your website and you will also encounter problems with sharing your page. A lot of social networks now try to parse your website when users share so that they can bring down extra information. If you don’t have content generated at server time, these share attempts will fail. Though this problem has been solved many times and I recommend prerender.io as nice open source solution, I have also wrote SEO server libraries to mitigate this problem. Though the search engine giants should really take it into their own hands to render your single page applications for content. Some people speculate the entire Chromium project is an attempt by Google to be able to load and execute all pages so that they can tie it into Google Bot and directorize all content rendered by JavaScript.
InfoQ: For someone that wants to start working with the framework, what do you think would be the fastest and most efficient learning path? Any resources you’d like to recommend?
Igor Minar: There are several good books on Angular, newsletters like ng-newsletter.com and many great podcasts here.
Julien Knebel: The official guides on emberjs.com are tremendous, every single one of them targets a specific feature of the framework. Otherwise I wrote a beginners in-depth introduction on Smashing Magazine (when Ember 1.0 came out) which, in my humble opinion, is still very relevant.
Brad Dunbar: It's maybe not the coolest thing to point out, but I always recommend reading the source. That's where the action is and if it's a mess you'll know it. You'll become very familiar with your choice of MVC framework so if you can't stomach the source you may as well hang it up.
John Munsch: If the person in question is already familiar with JavaScript I would recommend picking a small project (four or fewer distinct views making up a web app) and implementing that entire project using the framework in question. Building something, even something very simple, all the way to completion and actually deploying it for use is very different from "playing" with a framework. You are forced to solve some specific problems and really start to understand some things that are otherwise easy to skip because they may not be the fun parts of learning it.
Julio Cesar Ody: Make as many mistakes as you can in pet projects, but be extra mindful about them. By that I mean it's futile to try and nail everything in the best possible way right out of the bat, and it won't help you get there faster.
Then refactor your own code over and over, keeping in mind what you're looking for is a scenario where you're putting a bunch of components to work together to become a full application, and you need to keep them as independent as possible.
I've written a free booklet on this, with an emphasis on Backbone.js, which of course I'll recommend.
Thomas Davis: Depends on your learning style, I generally prefer to just jump in and start hacking away. I have received amazing feedback on my video tutorial for Backbone.js which can be found on Youtube.
InfoQ: Now that MVC framework have become mainstream, how do you think they need evolve in order to better fulfil developer needs? For example what features do you think they’re still missing?
Igor Minar: Mobile, testability, mobile.
Julien Knebel: Real time data synchronized between backend and multiple clients would be the next logical step. Meteor.js seems to go this way so I'll surely give it a try soon.
Brad Dunbar: I'm not sure about this one. I tend to submit patches for things I think Backbone needs and not all of them are good. :)
John Munsch: The easiest answer is that something like the usage numbers on ngmodules.org tells you some of the solutions that developers end up having to seek out over and over. Anything that ties the front-end framework to HTML/CSS frameworks (like Bootstrap), file upload, internationalization and localization, etc. If hundreds of developers have had to go find it and then took the time to go mark on a website that they use it, you can bet that thousands more also use it but never bothered to share that fact. That's the easy answer, but I'd actually plug two things I don't think get the love they ought to, validation and no back-end.
Validation
Client side validation is usually wanted and for some pages can be very complex. We have pages where many dates need to be tested against each other to make sure they occur in the correct sequence, and many other variables have various constraints as well. Then we send them up via an API call to the server, which turns around and tries to do the same stringent validation because you can never rely on validation client side. Our back-end is not written in JavaScript so we can't use a common library of code to do the validation and we get to build two sets of the same code in different languages and give ourselves twice the likelihood of making a mistake in some edge case.
Why not let me describe the data with a JSON Schema and then make it easy for me to use that for validation on both sides of the API call? I would like to see that made easy.
No Back-End
There was some buzz about this last year as a term of art (for example, nobackend.org) but that's kind of died down. But the idea itself still seems to be going strong with Firebase, Hoodie, Backendless, etc. I think it's a great way for some developers only familiar with front-end work to have a way to do a complete app without needing help from someone to do the back-end. But even for someone like me who could comfortably build the front and back-end of an application it provides an easy way to prototype an idea or get to an MVP.
Julio Cesar Ody: It's hard to say. I think a lot of ideas are born out of misconceptions about modularity, for one, so the more features mindset is one I've historically fought in the past.
But I think React.js has the right idea about it, in that it gives you a component-driven approach to building apps, and it's hard to do anything terribly wrong if you just follow the examples. It also abstracts some hard problems such as DOM performance and it pretty much gives you that for free.
That's the kind of problem no one wants to spend any time solving in the course of building an application, so that's a step in the right direction.
Thomas Davis: Client-side tooling and MVC’s are making fast progress in the right direction. I actually believe that server API’s are lagging behind at this point. There is no real convention that people are following when it comes to building RESTful API’s which makes it difficult for client-side models and collections to bring down data efficiently. Error logging on the client-side still needs some work but attempts such as trackjs.com are making progress there. How events are handled on the client side could also use some work.
About the Panelists
Igor Minar is a software engineer at Google. He is the lead of the AngularJS, practitioner of test driven development, open source enthusiast, hacker.
Matteo Pagliazzi is a passionate software developer and an open source contributor.
Julien Knebel is a self-taught interface designer and a front-end developer living in Paris where he is freelancing for some of the biggest French companies.
Brad Dunbar is a JavaScript programmer and a frequent contributor to the Backbone and Underscore projects.
John Munsch is a professional software developer with over 27 years of experience. These days he's leading a team building modern web app front ends with AngularJS after a couple of years spent doing the same kind of work with Backbone.js, Underscore.js, and Handlebars.js.
Julio Cesar Ody is a software developer, designer, presenter, and wannabe writer who lives in Sydney, Australia.
He works a lot with mobile web development, and has a built a handful of tools which he's very proud of.
Thomas Davis is the founder of backbonetutorials.com, co-founder of cdnjs.com and a developer for taskforce.is. Also a daily contributor to many other open source projects which can be found at github.com/thomasdavis.
The Web Platform has gone a long way since HTML5 was first made popular and people started looking into JavaScript as a language that could do build complex apps. Many APIs have emerged and there is an abundance of content out there about how the browser can leverage all this.
This specific article series will go a step further and focus on how these powerful technologies can be leveraged in practise, not to building cool demos and prototypes, but how real practitioners use them in the trenches. In this (post)HTML5 series, we'll go beyond buzzwords and get practical insight from experts about what has actually worked for them. We'll also talk about technologies (like AngularJS) that go a step further, and define the future of how the standards and web development will evolve.
This InfoQ article is part of the series “Next Generation HTML5 and JavaScript”. You can subscribe to receive notifications via RSS.