So it's 2015. You have a stellar back-end system: things are distributed, you're employing micro-services working in isolation maybe, everything seems to shine from your load-balanced heaven. This little beast will power your front-end experience and surprise surprise! - you wake up one day stunned by the criticism of people starting using it - "Why is it slow?" :) Yep, these users have absolutely no intention being confined to the boundaries of your app user flows. Driven by the smartphone boom you only have 6 seconds to keep your visitor until the moment you're idle again fishing in the market for the next 6-seconds visit. It's ridiculous and fun in the same time actually :) As a result it's an effort in itself finding non Bootstrap-alike websites. The word du jour seems to be performance on all levels - be succinct in ideas, be fast in load times, be responsive and obey the medium. Add to this the fact that you're running on a single UI thread and you have a story to tell.

How performant people are fishing in the market I can't really elaborate upon - we're lucky to have an incredible CEO shielding us from such details and keeping the ship together - we love our market and definitely felt lots of vice-versa, all good here. What I will tackle though is how we keep the ship afloat: running systems that is. Welcome to a series of posts describing our internal architecture decisions in regards to the various moving parts that form opening as a homogenous technical stack. Far from being a JavaScript authority this is simply our experience building our own front-end, please view it as such - it's what worked for us. Kindly accept our humble apologies in advance should any information in here be incomplete/inaccurate - we welcome good feedback and will adjust everything accordingly should this be the case.

Part one: Front-End.

"..we don't pollute our code-base with JavaScript"

My heart sank in grief hearing this sentence at some point. While I can certainly admire and respect the reasoning behind this (the context was completely different) a reality check is due here: incredible languages like Clojure, Erlang, Rust will not be in our browsers anytime soon. Are all developers Scala developers with 100k+ salary marks? Do they have to be? Why not explore this JavaScript territory a bit more and have it simple, accessible, performant too? Most developers are here anyway, let's fix things out a bit.

The problem

More often than not it's this front-end part where the bulk of your user interactions will happen, event clicks intertwining with async requests and fast refreshes. In all this chaos you need to hold state. At any single point in time you need to know how your application looks like. Immutability is nice and solves lots of headaches but have a look at your memory. Yep, you're running in a browser, crammed in a tab. Hi!

Another systemic, deeply entrenched problem: mutating data. In doing so you ensure endless nights of debugging: properties out of sync with each other and interface out of tune. You cannot tell your variables apart, need to re-sync pretty much all the time and this quickly escalates to a one way ticket to the cuckoo land. Neither the best performing back-end in the world or the best binding library would save the day once your user starts panicking - and with each event passed the system as a whole feels less and less snappy.

Approaches

For interface issues solutions like Angular exist. Bind my variable to that DOM control. I remember loving having this privilege with all the $digests that it involved. Angular is nice but has a lot of abstractions. Wait, what's the difference between providers and services? There's a StackOverflow for that sure or Angular source and documentation, it's even fun but it won't really fix the underlying issue. You don't need to sync DOM controls anymore, you need to sync scope variables now. Also, how many watchers are in there again?

Beginner JS devs are generally good with implementing spinners - everything loads all the time. Then ad-hoc jsons, ajax calls, console logs and if things really turn south end up refreshing the page.

Advanced JS devs fare better: are backed by backbone models which when changed trigger promises that perform callbacks which control things within the interface. Sometimes callbacks fight in which case a page refresh is due.

All of this is happening while senior devs cannot be called in to help assessing such issues, they're too high-level and expensive for this. Code reviews (when they happen) tend to happen across similar skill-sets, either jQuery-jQuery or Java-Java, never cross-systems.

Far from being the only approach (we're blessed with an abundance of architectures and libraries here) this describes a typical scenario employed by many of us today.

Jump into the band-wagon

We love React.js. It doesn't change the basic concepts and it's subtle. You have your same unassuming DOM element with a few new abilities (has its own state, you can initialise and caress it as much as you want). It can pass its properties to its children. The guy doesn't control anything, it just gets refreshed - two way binding is a rockier road. Problem stays the same but this time a predictable application state will always control the interface, not the other way around.

A few good gains already:
- You're faster. Components get rendered in memory not inside the DOM, DOM only updates when/where needed.
- It's accessible. Devs will initially freak out while realising what JSX is but in a few days' time they'd be happily churning out beautiful controls - productive and entertained at the same time.
- You can decide where rendering happens - server or client?
- You can finally do mobile the nice way via React Native
- Together with the whole JS crowd you can do multi-platform desktop apps too.
- Most of these steps can be achieved via configuration/minimum efforts

Are we still talking? Sweet, what's the catch though? The catch is the fact that JavaScript takes over - at times you're not even sure about the window object. With this it becomes even more important to be able to properly manage your data flows. Welcome to Flux: front-end data stores communicating via actions. Need lists? Point them to the appropriate data stores. When stores update so will the lists. A model changes the view, one tiny good sign already. Problem's still there though, how do we keep these stores in sync? Here's another area where you can really have a saying in.

"..but it almost looks alive, Jim"

This is the land where fear takes over - TypeScript, schema validations and all sorts of exceptions. Just think exceptions a little, don't they look a bit like unconditional GOTOs in code? They are definitely useful, use them the wrong way though and you end up with in the same point. What happens with a json object not passing validation? It most probably gets discarded. Static typing helps sure, we're better at removing of a good number of potential issues but not flaws in logic. Also, enforce strongly typed JavaScript and I would argue that your regular happy JS dev would end up to terrifying nightmares having to reason about transpiled ScalaJS code.

Fear not, there are clean alternatives.

One is Redux, enforcing immutability. All your data stores are immutable and you produce output by filtering these stores, cherry picking the properties you need. Beautiful & clean-cut, we have a reducer - another good sign. This guy's output gets mapped to our component's state (the glorified DOM element that is) and we're really in a much better position. Actions will trigger reduce functions that filter data. Interface is in sync all over the board. All this data being immutable our properties end up not stepping over each other and we're pretty happy with the outcome - our DOM is docile now. Change everything by triggering an action. Simple to code, easy to debug, concise. How well does it perform though? This is what needs assessment - immutability usually has costs in memory usage and we live in user browser land not inside a sandboxed, distributed environment. Each use-case has different requirements and you may be grand but yeah, this is definitely an area you want to assess.

Say hello to another project to love, Baobab.js. This guy is a tree holding your data. It provides access to branches in the data tree and it's damn serious about its job - it's really really efficient. You can have it mutable, you can have it immutable. You get various dynamically computed combinations of your data via Monkeys (lazily executed facets - reducers pretty much again, yeah). With a difference though: they are stored in the tree as well. How is this cool? They combine data from different branches together and you can tweak them at will at run time should you really need to while still preserving a single source of truth. THEY are the things that don't pollute your data, to come back to an earlier sentence - exporting your tree will not export its monkeys.

Good. Changing a property updates others and we end up with an interface that looks composed. Now, who's responsible for changing the damn property again?:) What if I'm actually using Angular and would like Baobab in charge there? Or how about changing the whole model library, replacing it with say Immutable.js?

Meet Cerebral - a state controller with its own debugger. This thing is your brain, the bulk of your front-end business logic goes here. It can trigger flows of actions (action 1 in sync, then actions 2&3 in parallel, when everything's done run action 4 - cleanup maybe). These flows are being referred to as signals in Cerebral slang. We're being given access to all our state history (you have a Chrome plugin helping you replay these actions, you'll love this) and it glues really well the data in your tree with the state of your components. Need a different data tree? Change the model library. Love Angular? Change your view layer. Debug? Check, there's your whole model in the console. You're ending up happily triggering signals and that feels like a lot more natural way of expressing intent - "my desired objective is this, actions are just steps taken towards reaching this objective". This is actually a major pain point while working with different Flux implementations - Reflux for instance. It's so easy to pick it up that you'll be firing Reflux actions for everything all the time. How do you construct your data tree? Sync actions :) With all this said we love this little dude, it's a really nice way of getting into Flux. For a newcomer this would be a really good candidate to play with.

We're still talking performance.

Module bundlers (Browserify, Webpack, System.js, etc) are really well described - not my purpose to get into details. They help you bundle your modular code together, add tremendous dev-value and take care of lazy loading of extra chunks of functionality only when you need it. But besides the obvious you also get ready for another incredible feature in the making (via ES6 exports): you get the ability to strip out incredible amounts of dead code when you transpile to js. Rollup.js is a pretty interesting project - it's another module bundler figuring out what you require() from your code and only preserving that. Zero efforts payload slimming, how cute is that?

When was the last time you checked your minified/uglified javascript files for junk code? That thing you fetch to each visitor and are paying dearly for in terms of bandwidth costs, loading times and potential sources of functionality trouble.

Many thanks for reading and keep following us for a Star-Wars saga kind of feel:
Part two - Adventures in Back-End: How we stopped worrying and still don't understand Mesos

-

Ireland is ranked the best country in the world in terms of empathy and people doing good for others. Feel free to connect with the tech community in here, you'll meet incredible people. If lacking ideas on how to engage you can start here: http://irishtechcommunity.com/
Welcome aboard!