Web development has drammaticaly changed over the past 5 years. Frameworks like Rails imposed themselves as the go-to choice for an increased productivity; new stacks like NodeJS emerged and offered alternatives ways of tackling web products development.
Despite all these goodies offered by these tools, web development often ends up being way harder than what it should be. Teams sink in a never ending bug list, often adding unneeded techical complexity in the attempt to offer a better user experience and hence very quickly transforming the application in an uncontrolled ball of mud.
From my direct experience in building public facing web products, there are few core ideas that have to be the pillars of any web products; these are language/framework agnostic – even if certain tools support these principles better than others.
These reccomendations are mostly related to a scenario where a pure single page web app is not a viable solution(check the this section for a more in depth analysis). Some of these principles are appliable even if you are targeting that style but might be less effective.
You want to have a very clear idea of the browsers you have/want to support. Building a product that works only on HTML5 friendly browsers while the 50% of your audience is on IE8 is not the best way to give your product the right boost. If you are replacing an exisiting product use Google Analytics historical data to understand the current browsers segmentation, while if you are building something totally new invest some time in understanding who your customers will be. Knowing your audience can influence heavily the architecture of your application: a single page app can be a perfect fit for a mobile only app( most of the mobile browsers are HTML5 friendly) but it might be a bad choice for a product that has to be consumed by less modern browsers.
Use aggressively progressive enhancement techniques
What this really means?
Go for multi layered enhancement approach.
- Look at what HTML5 features are available on the browsers you want to support and if possible rely on them(datepicker and validation are two good examples of HTML5 features that are getting more and more support).
The advantage in this case is a consistent reduction of the code you have to take care of over time; because HTML5 features are natively built into the browsers you will have a performace boost for free. Also they are often already supported on mobile browsers, giving for free a native experience in the mobile version of the product.
Prefer html snippet over JSON
JSON is extremely powerful and easy to use, but it’s not the solution for everything. Often we need to pass data from the server side to the browser as a consequence of an AJAX request to build new parts of the interface.
Unless you are thinking of consuming the exposed JSON data from an heteregenous set of clients you should just expose HTML snippet that you can then embed directly into your page.
This approach gives you:
- Progressive enanchement out of the box.
- A substantial reduction in client side computation, something that is critical for less modern browsers.
- A massive reduction of of your front-end code spread If you let the server-side to build the HTML snippet you you can use your favourite markup/markdown without the need of hand rolling your version client side or importing yet another dependency into the browser.
Use HTTP Status codes
The HTTP protocol contains everything you need to control and define the interaction between different parties in a scalable and fault tolerant way. When you need to return a specific status to your ajax call there’s no need of reinventing the wheel sending any custom JSON object to say that an error happened or that the specific operation is not acceptable, just use the right HTTP status code. Embracing a HATEOAS architectural style can help you in shaping your systems and APIs, going beyond the basic CRUD with a more holistic view of your system as a good citizen in the HTTP stack.
Leverage HTTP caching
Thr HTTP protocol gives you a wide range of caching options through header directives. Before introducing a cache at the domain model layer ask yourself if the same couldn’t be achieved at HTTP level.
Think about resource shareability (urls with resource id)
The web is really about sharing and URLs are the way we share resources.
Use URLs containing the resource id to epxose the different states of your resources to the world and use authentication and authorization layers to control resource access.
Don’t be tempted to to trade off unicity of the resource URL with the pretty link bells; links that are easy to read and rember for humans are a nice to have, but not all the time this style supports the needs of your application. Even if your web application doesn’t demand the share sharing this is a valid test to verify the solidity of your system: would it be easier to expose a resource to a third party? Is a specific state of a resource uniquely identified by a URI? If the answer to these questions is no there’s a clear smell that the application is not using the right semantic to move from an internal state to another.