If you look at the history of the development of desktop applications, it is clear that it began with powerful servers that could send text screens to thin clients. Thin clients gave the command that the server was processing and then sent the new screen back to the client.
Over time, the equipment became cheaper and we came to the current model, when the client does a significant part of the work, and communicates with the server only in order to obtain information, save information or give a command that must be run in a protected, controlled environment.
Now, if you think about it, in those days it was easier to develop, due to the fact that all users were equally limited by the hardware.
Unfortunately (for developers), the restrictions imposed by this model are also completely unacceptable for end users. They want responsive, fast, beautiful software, which is almost impossible in conditions where any small action leads to a request-response to a remote server.
')
Web Interface Evolution
You can see a similar evolution in web development. We are in a state of changing paradigms, and the further, the more difficult it will be for applications written in the old paradigm. Why use something that is not responsive and gives little interactivity when we have alternatives that are free from it?
UI architecture is a very difficult design problem, and even if large companies have invested millions of dollars in its solution over the years, we still don’t even have “One right way” to do it. Many JavaScript “MVC” frameworks (this is almost the same bad term as server MVC frameworks) have appeared over the past years and are fundamentally different in how to apply the ideas of the UI architecture of the last 50 years to the web.
Choosing a framework
We have tried many frameworks, but for the sake of brevity, I will describe the four most popular ones: Backbone, Ember, Knockout, and Angular.
Before starting, I want to say that all of these are really amazing projects with deserved popularity. There is no such thing as a “Silver Bullet” in the design that would be good in all situations and problems, and each of these frameworks has strengths and weaknesses.
Our situation
We have (approximately) 250 thousand lines of industrial Rails application code. It spent most of its life following the Rails Path, and we learned a lot from it. The application contains an unreal amount of business logic. Thus, scalability and flexibility were two key criteria that guided us when choosing a framework.
Ember.js
Based on the documentation and Yehuda Katz (wycats) conversations about Ember.js, this is basically an attempt to make Rails on the client side.
Ember is the most ambitious framework available now and its strengths are obvious. It deprives you of the choice in some cases and it is quite convenient. In particular, I like their approach to routing (State Manager / StateManager), I think this is much better than other implementations.
The weak side of Ember is the result of its advantages; if you don’t want to take the Ember path, tough times are coming for you. If you encounter a problem, you are dealing with an extremely complex framework, and most likely you will not be able to quickly solve the problem. Ember has only reached version 1.0 and will change significantly in the coming years. With frameworks that have such a level of presence in every aspect of your code, upgrading can be a difficult challenge (it took us more than a year to complete the Rails upgrade to version 3).
The last straw for me was how Ember controls your architecture. We have enough skills to make our own choices, so I believe that working with the fact that it imposes so many restrictions on us is a bad choice.
Angular.js
Angular uses an approach whereby in HTML and JavaScript there are no key things that make it more suitable for creating complex interfaces. In the case of JavaScript, what is needed is the observed objects. For HTML, the missing part is some form of templating. Since both are extensible languages, what Angular does is add such features.
I'm a big fan of Angular. It provides a transparent separation between views and business logic, a component implementation that combines behavior and structure - what the current web really needs. It also contains a dependency injection (Dependency Injection Framework), something that many developers consider redundant, but I think this is a good idea.
The place when I stopped agreeing is how templateization is implemented. I have been involved in web development since 2000, and during this time I have seen a steady tendency to distinguish between three parts of web technology: style, behavior and structure. I saw (and was a part of) this movement, and I think things that encourage behavior in HTML and HTML in JavaScript are a bad way. After all, what's the difference between
onclick="foo();"
and
ng-click="foo();"
In an environment like Xcode, I have no problems with this style of binding in the view, since the “view” is not a code for me, but a design surface. But since we are building the web differently, I think this is a bad direction.
I would not even consider this a weakness, rather a difference of approaches. I think Angular’s ​​weakness is a cumbersome API, the fact that web standards are going in a different direction than Angular, and that abstractions are fragile enough. It is easy enough to be outside the regulated Angular world, when you need a deep understanding of how it works, and where / how you return.
The decisive disadvantage for me was how difficult it is to make my own directive (directive), which I consider the most valuable feature of the entire framework. Throughout my career, the only platform that came close to the level of anguish when trying to expand it was server controls in ASP.net WebForms. This is a solvable problem, and I think if we were now at the point where Angular reached the second or third version, it would be my choice.
Knockout.js
Knockout takes a Microsoft-inspired MVVM approach to frontend. They have a powerful language for data binding (databinding), and html bindings to view models. They have a basic router, and that's all. Knockout is not so much a “framework” as a good data binding library.
I think Knockout’s perfect application is when you make a “hybrid” application, when you have interaction between page reloads, but the server still holds most of the logic. If this is your case, then you have modest needs for the client side, and the separation of state and behavior is most likely what you need.
The weakness of Knockout is that if you need a significant amount of client logic, this will become part of its solution.
Backbone.js
Backbone is the most popular front-end library of this type, but also the simplest. Backbone's philosophy is to provide the minimum set of things needed to structure a front-end code on the web. You can very quickly learn how to use Backbone (and read the code base from beginning to end in an hour), thanks to its simplicity.
Backbone is worth using when you have modest needs (or initially moderate, but slowly growing). Backbone is even more of a philosophy than a framework. Backbone also has a surprisingly active community, which means that you can “build your own framework” by choosing from a variety of third-party extensions and libraries. Backbone is very JavaScript-based, that is, if you understand the language in which you write, you will understand the framework, as it does everything in the style of JavaScript.
The weakness of Backbone is that it doesn’t really do so much on its own, and you do yourself a disservice if you don’t know what to plug into it. This “javascript” can also be a hindrance, since many “web developers” have scant knowledge about web technology, and if you are one of them, you can easily get lost with Backbone.
Backbone.Marionette
Marionette takes the position that if Backbone offers the necessary minimum for the structure of any type of application, large applications end up with a huge amount of generic code. Marionette provides the structure necessary for this kind of application, and also gives guidance on how to organize large amounts of code.
The reason we chose Marionette is their approach to code organization, which largely coincides with ours; separation of large blocks of code into smaller ones that communicate with each other using well-defined and simple interfaces. Separation of control and computation, make the code of representations as declarative as possible, and control the code as high as possible. And also follow the established patterns of work with large and complex code bases.
Marionette solves the biggest problem with Backbone - all this sample code in views. It is also easy to build your own component architecture (which is too difficult now in Angular), and get the minimum structure for everything you need (as opposed to Knockout). It will take work to complete the good architecture and build the infrastructure, but considering our needs and the current state of other libraries, I think this is a good compromise.
UI is difficult and there is no Silver Bullet.
This is an assessment of the specific situation and point of view, and I believe it makes sense for our product and our development team. As I said at the beginning, all these options are perfect for their purposes. If someone says to you, “I used the X framework and it’s bad, but now I use the Y framework and feel like I’m traveling through the sunny fields on a magic horse.”, Most likely he just made the wrong choice the first time.
Original Written by Matt Briggs.