John Henry Mahr

John Henry Mahr Summary

Building the modern web client

Steps Forward.

With ever growing browser support for html5 standards and the advent of the modern JavaScript ecosystem, it now possible to build web applications that can operate as more than just a skin for a server driven application. The modern web client brings its own independent application architecture to the table allowing for enforcement of business logic, input validation, user preferences, and user flows without constantly deferring to a server application that sits on the other side of a Internet connection that may be inconsistent, slow or unstable. A new level of responsive user experience that is much closer in feel to a native application is now possible while retaining the open, cross platform advantages of a web application. This change in paradigm from a server centric model to one where the client has a larger role has transformed the basic nature of the Font - End / UI Developer role and disrupted the division of responsibilities within the development team.

Position of UI Developer in relation to other roles. A diagram that visually represents this concept as a continuum from user centered, humanistic concerns of UX (an ultimately business as well) on one end to the technological concerns of the server application on the other with the UI developer placed squarely in the middle of the spectrum. It shows the concerns of the UI Developer overlapping onto both the visual design and application design domains.
The role of the UI Developer within the continuum from humanistic concerns to technological concerns. With credit and much thanks given to this blog article.

The role of the UI Developer

The UI Developer role sits in an unique position on the development team. In a sense, the UI Developer must be the bridge between two very different worlds and ways of thinking. On the one side are the user focused, “soft” (in a sense of be less definable by nature) concerns of UX: usability, interaction design and visual impact. And on the other, the technological focused, “hard” concerns of the application developer: api efficiency, security, versioning, separation of concerns, and performance. A good UI Developer must at least have an “eye” for design and what looks good, a sense of when a user experience is or is not working on the one hand, and on the other hand also have strong coding skills, an ability to troubleshoot and debug across environments, and manage a build infrastructure. And on top of this the UI Developer often ends up being one of the primary advocates and implementors of accessibility on the team. So it requires a developer who is at least somewhat comfortable in UX/Design application such as Photoshop, Sketch or Illustrator as well as the primary skill set of writing JavaScript, CSS [or Less, Sass, Stylus…] or HTML in an editor or IDE, or logging into a Linux server and modifying an Apache or NGINX configuration file with vi (as an example). A good UI Developer needs to embrace these various aspects with a strong curiosity about how things work, how they can be improved and most importantly must posses a fearlessness to jump in and work with technologies, comprehend standards or tackle problems that they may have never encountered before. They need to be, at a minimum, aware of nearly every aspect of the web page, and whenever possible, understand the technical considerations, specifications and general best practices that underly and define those aspects.

Unfortunately, despite of all these varied skills and requirements, the UI developer is often in a position of justifying the significance of their role and the value that they offer — especially in an enterprise environment. While server side technologies are very mature at this point and their role, infrastructure and processes are more or less well defined and their value is obviously paramount; front end technologies present a value proposition that is less clear. It is understandable, considering the period of rapid growth, development, and radical change that Front End technology has recently been going through, that management or leadership is often unclear of the scope of work, skill sets required, and complexities involved when implementing these technologies and how those challenges relate to the performance and efficiency of the rest of their current stack. There is a temptation perhaps to stick with what has worked and been proven up to this point and not evolve the stack to leverage these new UI technologies. However, the web in general, and more importantly user expectations of how the web should work, are evolving. Users are beginning to expect a more robust, “app” like, experience, and are beginning to loose patience with applications that make them wait those extra milliseconds for the extra round trips to the server for every action. We now have the tools, technologies and the opportunity to deliver that robust and responsive user interface. But to fulfill this potential I believe the UI must be treated with the same seriousness and dedication that is given to server centered applications currently. Operating with the old model — where the server is the center of all concerns and the UI is a minor implementation detail — is going to become less and less feasible as the general shift towards a “thicker” client continues. The client is becoming one of the primary pillars of the next generation of web based applications, no more or less important than any other pillar. It is time to move outside of the comfort zone and let the UI take its place along side those other pillars of the the technology stack.

Getting Serious

To be clear. This is not a concept or lofty futurism, but something that is already well underway. There are many companies and development teams that are already implementing robust client side applications. Additionally, all of the Browser vendors are relentlessly pushing browser technology forward at a pace never before seen, providing the essential foundations for the client of the future. Service workers, web workers, local storage, web sockets, server sent events, flex-box, HTTP version 2, and now even web assembly — to name just a few (see this for a visual representation that is quite fun) — all represent major, paradigm shifting changes to the capabilities and role of the browser. As is often the case with the web, just keeping up and not being totally left behind is the real task. And right now is the age of the client. That is why it is time to get serious about UI development and to give it the attention it needs. UI development needs proper code review, real oversight, security auditing, performance testing and, more than anything, to be part of the discussion when it comes to architectural planning and decisions. Choices made on the UI side of the fence matter and will have far reaching implications for the entire team as well as the enterprise. If we can accept this fact and embrace it I believe the opportunities for advancing the web experience are tremendous.


In Depth: The Client Application Stack

No bit is faster than one that is not sent; send fewer bits.

How does this new, more robust UI layer fit into the greater web application technology stack? It is not a question that can really be answered in a generic way. Every business need, architecture and technology stack has its own set of requirements and special challenges. But lets try anyways — because its fun! The following is one concept of how it might work. There are so many technologies involved that creating a visualization can easily get unwieldy and become pretty useless. I have done my best to simplify a basic idea about an architecture were the UI layer is more independent of the server. These are broad strokes for the sake of argument and discussion that leave out the many details a real implementation would involve.

Flow diagram for a Thick Client Front End App Describes a possible architecture and data flow for an application where the client has more responsibility
A simple example of a client application stack.

Of course it all begins with the client making a http request to the web server of some sort and receiving a response body containing an html document. The page may contain a basic mount point (DOM element container) for the front end application to be injected into or there may be a need for an initial server side rendering for SEO reasons. There is a strong argument to be made for doing an initial render server side, or doing the app layout rendering in a middle-ware layer running node.js server. It allows the page to display initial content before the JavaScript application has been downloaded and initialized. This can give the perception to the user that the app has loaded faster. It is also likely the server would be embedding initial bootstrap data for the application to avoid any immediate additional data requests — also a nice optimization. Ideally, at this point, the server (or middle-ware) is done producing html. Additional domain interactions would be in the form of api requests using whatever standard is appropriate: REST, SOAP, GraphQL — whatever the overriding architecture demands. In the case of an authenticated application, these domain services would also still maintain the session by checking request headers and responding as appropriate when a session expires.

Once an application has been bootstrapped onto the page it can then use its own internal data store to maintain its state and respond to user interactions, internal events, or subscribed stream events (in the case of the reactive model -- something I am very excited to learn more about). The diagram illustrates a data flow that is essentially the Flux pattern were data flows in a single direction. An application event (or Action ) causes a change in application state which in turn causes the application to re-render its display. Data flows down to the store through event handlers and the state is mutated there (or a new state is produced if the state is immutable). The store is responsible for transforming the state and passing it back to the view engine.

Bellow the state layer I have placed the somewhat generic concept of the model. The model is a placeholder for the connection layer that handles making the api requests, or subscribes to event streams using XMLHttpRequest, Fetch or even WebSockets. It also needs to provide an interface to the store for dealing with asynchronous behavior using something like events, promises, callbacks, generators (sagas), or observables. This is where the connection to the back-end or other services is handled. Additionally the model could provide additional functions related to the data such as hydration of a data set, aggregation of multiple requests, or transformation from a service schema to something more easily digest-able by the store. Every layer above the model is unaware of any specifics regarding details of communication protocols, only the interface provided by the model — making swapping the model code out with a different implementation without affecting the code in the layers above theoretically possible.

Because of the possibility for data transformation at the model level I have also marked the model as a layer that could be hosted on a node.js middle-ware server. Most of the discussion these days about server hosted JavaScript middle-layers center around doing an initial render on the server as I mentioned above. Even if pre-rendering is the use-case with the most obvious benefits I believe the middle-layer can have a place in the service connection. It is essentially a layer between the client and the application server for api communication. It is certainly a more complex process than a direct service call from the client and there would be concerns in terms of network latency, scaling and timeouts. But under the right circumstances it does have the potential benefits of offloading some of the data processing to a more predictable environment and optimizing the transfer payload between the middle-layer and client. Not all users have the benefit of a fast device on a fast network and many apis cannot be modified for reasons of backwards compatibility or other legacy concerns and may return payloads that are unnecessarily large and bloated, or in a less than optimal format (xml for example). The addition of a transformation, optimization or aggregation layer (which may also implement its own cache of some sort) could be very beneficial in these cases.

So in summary the server bootstraps the application and maintains the session (if applicable) and passes primary control over to the client which enforces validations, business logic, and UI state. The client leverages such technologies as client side routing, local storage, fetch and web sockets to keep communications with the server (or other web apis) as streamlined and efficient as possible to insulate the user from the negative effects poor connectivity. It is true that limitations of networking will always have a major impact on any distributed system such as a web application. No amount of client side JavaScript can defeat the realities of network latency and the laws of nature. But with cleaver and well thought out User Interface design and implementation the users can be given an experience that is able to more gracefully deal with these limitations. This ability to better deal with network link shortcomings along with proving a speedier, more robust UI in general makes the client application stack approach a strong choice for complex pages that require the capabilities of a web application.

UI Toolset

This is my preferred tool set for development at this moment if all other factors are equal. I have only been using this tool set for about 8 months so it is relatively new. But it has proven to be a real advancement over what I have used in the past. The combination of React and Jest has made front-end code with high unit test coverage a reality in my work-flow because of the way it abstracts DOM manipulation. I believe that the integration of these tools has allowed my development effects to rise to level I could haves only dreamed of even a year ago.

Learning: Reactive Extensions for JavaScript (RxJS)

A way to deal with asynchronous operations that are stream like and do not resolve to a single value, but a stream of value. Why? The request/response system fit very nice with promises: question resolves to answer or failure. But if instead of request/response we think in terms of subscribing to an event stream it does not work as well. The reactive approach is all about responding to changes in a stream that is using a push like technology: web-sockets or server sent events. There seem to be hints that this is the future, or a future, of the communications infrastructure of the web. So it would not seem to be a bad technology to learn more about.

Visit Project Home


Investigating: Vue.js framework

I just cannot help but to be curious about this one. It shares many of the philosophies of React and Redux but has taken a different path of implementation. I am not giving up React or anything but I believe this may be a really useful tool. It brings back client side templates as a thing you can use (even if I have accepted JSX) and may in fact be more performant than a React app without the need for componentWillUpdate optimizations.

Visit Project Home


Other Tech Stuff

Some other technologies have had used in the past, or currently still use when I need what they provide.

  • Backbone, Backbone.Marionette, jQuery
  • Require.js (AMD modules)
  • Karma, Chai, Mocha, PhantomJS, Istanbul
  • Dust.js template language
  • Selenium Webdriver IO
  • Grunt Task Runner
  • Bluebird and Q promise polyfills
  • Moment.js date/time library
  • React Router, React Router Redux
  • Redux Form
  • Freemarker Java templates

©2016 JHM Consulting, all rights reserved