<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> Bitovi Blog - UX and UI design, JavaScript and Frontend development
Loading

Web Application Theory

Web Application Theory

Justin Meyer

Justin Meyer

Twitter Reddit

I've been attempting to organize how Bitovi approaches web application development. I'd like to draw a line from what users and businesses value (quality) to the techniques and tools we use to build web applications. I've organized my thoughts into a mental map:

web app theory mental map

It's a bit crazy, but it connects what users, businesses, and developers want (red) and the problems and constraints we face (orange) with solutions (green) and tools (violet).

Read on to understand this map and Bitovi's take on web development.

The Goal

Bitovi's goal is to create quality applications. The user, not the developer utimately determines quality.

quality is fast, error, free, and great UX

A quality application is:

  • Fast - response times beating user flow and attention limits.
  • Error Free - the site is free of bugs.
  • Highly Usable - a user can accomplish all tasks effortlessly with little training.

The Constraints

With infinite developers and time, a quality application will be produced, but budgets and timelines often get in the way of this extremely effective approach.

constrains

The most common constraint is time to delivery. Ideally, the solution would be to hire more developers. But those developers will need to coordinate, which introduces other problems:

  • Budgets - You can't hire infinite developers to work in silos.
  • Imperfect Foresight - It's impossible to always plan perfectly.
  • Skill Sets - Different developers are good at different things.
  • Communication Bottlenecks - Communication is quadratic for a given number of developers.

The Solution - Maintainability

Maintainability is how easily a codebase can respond to change. A highly maintainable app enables the most efficient development, which allows you to quickly improve the application, resulting in something that is error free, fast, and has a better user experience - Quality.

maintainability

Maintainability always pays off in the long run. But you have to fight human nature that often compels us to do what is easy and "works" instead of what is right and hard. This is why at Bitovi we try very hard to favor maintainability over all other concerns.

But measuring maintainability is hard. It cannot be measured by lines-of-code, Cyclomatic complexity, or some other form of static analysis.

For Bitovi, a maintainable apps is:

  • Documented
  • Tested
  • Deterministic
  • Modular

maintainability characteristics

A documented code base is easy to understand and use. We use DocumentJS to document our clients' code.

A tested code base can be refactored or improved with fewer regressions. We use QUnit or Jasmine to unit test our code, FuncUnit to functional test it, testee to automate the tests, and either Travis or Jenkins for CI.

A deterministic code base makes it easy for a developer to know where and how to add new functionality. This is something that JavaScriptMVC's generators provide - an easy way to create a module and its tests.

Good docs, tests, and determinism are essential, but modularity is the most important characteristic of a maintainable app.

Modularity and Thin Server Architecture

Modularity is the degree to which a system's components may be separated and recombined. A modular app is not wasteful - parts can be changed, replaced, or thrown away without affecting the rest of the app.

There are a lot of ways to break up a web application, but the best place to start is strong client-server separation. We're big believers in Thin Server Architecture. Thin Server Architecture means that you:

  • Do as much as you possibly can on the client.
  • Client and server communicate via services.

Modularity to TSA

We've been building SPAs and traditional websites for years with Thin Server and Fat Server approaches. The Thin Servers always work out better because Thin Server architecture:

  • Separates the application's logic in two domains:
    • Server - Data, Business Process, Security
    • Client - State, User Interface, Views
  • Specializes teams: Client and Services
  • Parallelizes development - Client and Services can work independently with fixtures.
  • Leaves you with services you can use with other clients.

Thin Server Architecture cuts your application in half by separating client from server. You can throw away an entire Angular, Backbone, or Ember client and startover with CanJS without touching the server. That's modularity!

For more information on Thin Server Architecture, checkout these slides by Peter Svensson, the person who coined the term.

If you're worried about search, there are services that can crawlify your site. We built something similar in about 2 weeks that could do 85 requests a second on a single EC2 xlarge instance. And Google announced they have started processing JavaScript when crawling sites.

Google's Fetch And Render Webmaster Button that processes JS

Services

TSA - Services - Rest

We strongly encourage creating and documenting RESTful services. For needs that REST doesn't fully describe, like retrieving relational data, we encourage adding some Rest Relational Alegbra. We document services like this.

Modularity on the Client

We build each module in our apps as it's own little application. Each module has its own:

  • tests,
  • test page,
  • documentation,
  • demo page,

and often its own styles, templates and more. Srchr's code has a lot of good examples of this.

Dependency Management

Client - Dependency Management - Steal

To build everything as its own application, a very good dependency management solution is needed. Although server based technologies like browserify have nice abilities and require less configuration, it is more difficult to make individual tests and demo pages and perform client-control actions like progressive loading. For this reason, we usually use steal, or RequireJS.

Styles

Client - Styles - Less

We use Less to help make CSS more maintainable. We also keep our CSS modular by namespacing styles within their module. Srchr has examples of this.

DOM

Client - DOM - jQuery + jQuery++

We almost always need to support IE8+. And even if we only supported modern browsers, jQuery still provides powerful event and ajax hooks. We also use jQuery++ for patching DOM behavior that jQuery doesn't include.

JavaScript Architecture

Client -> MV* -> CanJS

Previously, Bitovi organized our JavaScript within the Model-View-Controller pattern. We now use Model-View-ViewModel (MVVM). A ViewModel is more testable and modular than a Controller. It organizes and encapsulates state much better than a Controller.

With CanJS's 2-way binding, define plugin, and components, views and view models are easy to create and assemble.

For more information on the MVVM approach with CanJS, checkout the CanJS ATM video and read Data-Driven JavaScript Controls.

tl;dr

In summary:

  • Maintainability is the key to successful long term application.
  • A maintainable app is tested, documented, deterministic, and modular.
  • Thin Server Architecture is the best way to create modularity.
  • We tend to favor client-side dependency management solutions over server-side solutions.
  • MVVM is better than MVC.