I want to dive a bit deeper into the problems which rose from using Angular.js.
No matter how hard I tried to apply the best practices of the tutorial I found online on Angular I kept on having bad performance in the app. The things which you learn first and make Angular easy and cool turn out later to be the things to avoid.
I found myself switching a lot between different files. I thought I did well by deciding to group controllers, models, directives and views. This resulted in functionality of a feature being scattered over different files.
But the biggest thing was handling state. Handling state with 2 way data binding seems promising at first, but tends out to not only perform badly but also complicate some stuff.
As a first step I decided to put some thinking in how to make the app more performant. Being dissatisfied with the complexity and performance of Angular, the search for an alternative began.
What way of approaching UI would benefit performance and simplicity? or How to deal with complexity in large scale client heavy web apps?
Let’s start with defining what complexity is.
Looking at the definition of simple, what can we conclude about which elements of a computer program are simple or not. What is a one fold what is not.
Talk by Rich Hickey on complexity
One of the biggest problems in programming user interfaces is complexity in handling and maintaining state. State is the data in your program that is constantly changing. Keeping the state consistent with what the user sees is the hardest part. The interface, what the user sees needs to be synchronized with this data. This is where the trouble comes in. How do you know when the data changed, what is changed and what should change in the interface? Angular for example tries to ease using state with two way data binding.
State is the data which flows through your application. State needs to be maintained on changes. The more interactive your application is, the harder it is to maintain state. If you click a button here, something else happens there and maybe vice versa. How do you keep track of this?
Mutex and stuff…
Om is a Clojurescript library to be able to use React in Clojurescript.
Om allows users to represent their UIs simply as EDN. Because ClojureScript data is immutable data, Om can always rapidly re-render the UI from the root.
Thus Om UIs are out of the box snapshotable and undoable without much overhead or implementation complexity.
1 a group or system of different things that are linked in a close or complicated way; a network: a complex of mountain roads.
This is objective.
ORIGIN mid 17th cent. (in the sense ‘group of related elements’): from Latin complexus, past participle (used as a noun) of complectere ‘embrace, comprise’, later associated with complexus ‘plaited’; the adjective is partly via French complexe .
ORIGIN early 17th cent. (in the sense ‘combine, entangle, intertwine’): from Latin complicat- ‘folded together’, from the verb complicare, from com- ‘together’ + plicare ‘to fold’.
The antonym of complex is simple, which is derived from simplex.
ORIGIN Middle English: from Old French, from Latin simplus. The noun sense (mid 16th cent.) originally referred to a medicine made from one constituent, especially from one plant.
This is objective.
Easy is different than simple and often mistaken for. Easy means “achieved without great effort; presenting few difficulties: an easy way of retrieving information.” This is subjective since it’s relative to a person’s own prior experience and opinionated.
The Runner: a child’s flip book serves to illustrate Clojure’s notions of state, time, and identity. The book itself represents the identity. Whenever you wish to show a change in the illustration, you draw another picture and add it to the end of your flip book. The act of flipping the pages therefore represents the states over time of the image within. Stopping at any given page and observing the particular picture represents the state of the Runner at that moment in time.
The Mutable Runner: modeling state change with mutation requires that you stock up on erasers. Your book becomes a single page, requiring that in order to model changes, you must physically erase and redraw the parts of the picture requiring change. Using this model, you should see that mutation destroys all notion of time, and state and identity become one.
State also appears in web applications. As said before state is the data that drives your application. In web applications the interface the end user sees is most often the DOM. The DOM is the living collection of HTML components that make a web page.
There are a couple of difficulties in keeping the DOM up to date with your state.
Interaction with the DOM is expensive.
Because the DOM is a tree of html elements. Selectors, deeply nested.
It’s hard to observe the state whether it has changed or not.
Let’s take a look at the different ways to approach these two problems.
Two way databinding is a technique used to update the dom or state whenever one of the two has been updated. It’s used heavily in Angular.js for example. Angular uses so-called ‘dirty checking’ to check if a state has been updated. Dirty checking means it will check the state object every couple of mili seconds whether it’s different than before.
The immutable DOM present in React.js, a framework by Facebook takes a different approach in DOM manipulations.