Usually, when UI frameworks get compared, they get measured against each other based on metrics, such as widget count, theming capabilities, and asynchronous data retrieval features. Each framework has its strengths and weaknesses, but leaving all the extra features aside and reducing it to the core concerns of a UI framework, I only have a few metrics left that I'd like to be assessed. These metrics are, of course, not the only ones that are important in today's UI development, but they also are the main factors toward building a clean architecture that supports the principle of change:
- I can create encapsulated components with clear interfaces
- I can create larger components by using composition
- I can make components interact with each other within their hierarchy
If you're looking for a framework which enables you to take full advantage of component-based UI development, you should look for these three key measures.
First of all, I think it's very important to understand the main purpose of the web and how it evolved. If we think of the web in its early days in the 1990s, it was probably only about hypertext. There were very basic semantics that could be used to structure information and display them to a user. HTML was created to hold structure and information. The need for custom visual presentation of information led to the development of CSS right after HTML started being widely used.
It was in the mid 1990s when Brendan Eich invented JavaScript, and it was first implemented in Netscape Navigator. By providing a way to implement behavior and state, JavaScript was the last missing piece for a full web customization:
Technology
|
Concern
|
HTML
|
Structure and information
|
CSS
|
Presentation
|
JavaScript
|
Behavior and state
|
We have learned to keep these concerns as separate as possible in order to maintain a clean architecture. Although there are different opinions on this and some recent technologies also move away from this principle, I believe that a clean separation of these concerns is very important to create a maintainable application.
Leaving this view aside, the standard definition of encapsulation from OOP is just concerned about coupling and isolation of logic and data. This probably applies well to classic software components. However, as soon as we consider a user interface as part of an architecture, there is a new dimension that is added.
Classical MVC frameworks are view centric, and developers organize their code based on pages. You'll probably go ahead and create a new view that represents a page. Of course, your view needs a controller and model, so you'll also create them. The problem with organization by pages is that there's little to no gain of reusability. Once you've created a page and you'd like to reuse only some parts of the page, you will need a way to encapsulate only a specific part of this model—the view and the controller.
UI components solve this problem nicely. I like to see them as a modular approach to MVC. Although they still embrace the MVC pattern, they also establish encapsulation and composability. This way, a view is a component itself, but it also consists of components. By composing views of components, one can gain a maximum amount of reusability:
UI components embrace MVC, but they also support encapsulation and composition on a much lower level
Technically, there are some challenges when implementing components with web technologies. JavaScript was always flexible enough to implement different patterns and paradigms. Working with encapsulation and composition isn't an issue at all, and the controlling part and the model of components can easily be implemented. Approaches, such as the revealing module pattern, namespaces, prototypes, or the recent ECMAScript 6 modules, provide all the tools that are needed from the JavaScript side.
However, for the view part of our components, we face some limitations. Although HTML supports great flexibility in terms of composability because the DOM tree is nothing else than a big composition, we have no way to reuse these compositions. We can only create one large composition, which is the page itself. HTML being only the final view that was delivered from the server, this was never really a real concern. Today's applications are much more demanding, and we need to have a fully-encapsulated component running in the browser, which also consists of a partial view.
We face the same problem with CSS. There is no real modularization and encapsulation while writing CSS, and we need to use namespaces and prefixes in order to segregate our CSS styles. Still, the whole cascading nature of CSS can easily destroy all encapsulation that we try to bring in place using CSS structuring patterns.