24 Feb 2021

Two Types Of Web Systems

Too often, I see discussion (perhaps especially among management, but also among some developers) that seems to equate a client-side, web app style with "modern", and a server-side oriented web page with less in the way of client-side interaction, as "old-fashioned". While there are certainly good use cases for the client-side oriented web app, there are also many good use cases for server-side oriented systems. It is much like we still have many valid uses for desktop or laptop computers, even though smartphones and tablets are well established by now.

Nothing that I say here is being said the first time by me, but I thought it would be useful to lay out in plain language the two extremes. Keep in mind that there can be (and often are) cases somewhat in between these two cases, but it is still useful to know what the two extreme cases are, so as to think more clearly about which end you are nearer to.

CaseHTML rendering# usersuser experience with this systemsite is for...
1Mostly Server-sideon the order of 10high (will use site many times, perhaps every day)user to enter data or receive reports
2Mostly Client-sideon the order of 1,000,000low (if they don't like it, will leave and not return)user to purchase, click on ads, comment, or consume media

Number of users

In a classic server-side example, it is an internal site for the use of the organization. There may be 2 people who use it, or 200, but in any case it is supportable with a single server. Reducing the load on the server is not a primary concern, because one server can adequately support all of the users. Increasing the developer cost, by doing something that decreases the server cost, is not a good tradeoff.

In a classic client-side example, it is an external-facing site for people not in the organization that supports the site. There may be 20,000 users, there may be 2 million, or if you're one of the very biggest maybe 200 million or 2 billion. Anything that reduces the server cost, even if by only a few percent, is justifiable, even if it increases the cost in developer hours by a lot.

User experience with the system

There is often a tradeoff between fewer keystrokes or mouseclicks, and intuitiveness to a beginning user. The simplest example is a set of radio buttons vs. a textbox. If an experienced user already knows by heart the five possible values for a field, then having to take their hands off the keyboard to click on a radio button (or javascript equivalent) is a bad thing. If the user is new, and doesn't know what their options are for that field, then radio buttons or a dropdown are far preferable to a textbox. You can use javascript to try to get around these tradeoffs, at the cost of more code, but in the case of a classic server-side website a simple textbox is optimal, both from the user and the developer point of view. The users know what the options are, they know the number or letter which represents each one, and they can very quickly type into that box the one they want and then tab to the next, without taking their hands off the keyboard.

Other examples of this tradeoff are one page (simpler for people who have done this many times, and already know how this works) vs. multi-page wizards (which present less to the user at one time, and are thus less likely to overwhelm a new user with too many things to do), and the importance of images and logos (just distracting fluff for an experienced user vs. a reassurance that we are on the right site if the user is new), but there are many others. Google's home page (a single textbox in a mostly white page) works for general users because they use it again and again, but most consumer-facing websites need to be more engaging (and encouraging) than this, whereas that is just extra noise and distraction for an experienced user who will use this site an hour a day every day of work for years. It is a not uncommon occurrence that a webpage made for internal, experienced users which is "modernized" becomes much slower to use, because it requires more steps and more mouseworks, whereas the older webpage allowed them to simply type without taking their hands off of the keyboard.

Site is for

When the point is for the user to produce (rather than consume), and to do work (rather than be entertained), a simpler, plainer website is preferable. The user needs to concentrate on what THEY are entering, which may be extensive, and they do not need (or want) a lot of content to be presented to them (except perhaps a report which will mostly consist of text and charts, with a high content-to-fluff ratio). The user is here to produce, and has a definite outcome they want to bring about (record this transaction, generate a report, etc.).

With the classic client-side site, case 2 as we are calling it, it is the website which wants to bring about a certain result (purchase the item, click on the ad, etc.). The user is not sure they are wanting anything in particular, although they might, and it is part of the website's purpose to persuade them of this. If the user leaves, they may well never come back, and they may or may not have any particular objective in mind when they showed up. They may be window shopping, and we want to convince them to buy. They may be browsing content or connecting with other users, and we want to convince them to look at an ad. The website has the primary want or need, and the visitor is the one who needs to be convinced to satisfy that, rather than the other way around.

Casei/o focusdata priority
1keyboard,big screenconsistency
2mouse or touch,small screencollection

I/O focus

For many of the reasons already mentioned, in what we are calling 'case 1' there should be a heavy keyboard focus. If we absolutely must have a dropdown select or radio button or other non-text input, the use of javascript to make keyboard-based methods of entry work better, is highly desirable (whereas in general, case 1 will have rather less javascript than case 2). They have a relatively large screen (or more than one), and want everything to be displayed on it, and will find it annoying if they have to keep reopening different parts of the web page or web app to look at them.

In the second case, the user may not even have a keyboard, and if they do they are not using it as much. They may be sitting back, hand on the mouse scroll button, moving down through the screen without needing or wanting to do any other interaction besides reading and very occasionally clicking on something. Or, they may be using a tablet or more likely a smartphone, and entering text is relatively laborious. The screen size may be small, and the ability to easily fold away or hide any element not currently the focus of attention, is highly desirable.

Data Priority

In all cases, obviously, we would wish to collect all the data we can, and be certain that it is all accurate and consistent. The question of priority comes up, when we must choose between these two. In the case 1, consistency is emphasized. If the user wishes to log a transaction as "Account A gave $4.58 to Account...?", we will not save this, because it is incomplete. You have to tell us which account the money goes to, for it to be a valid transaction. The fact that Account A is $4.58 poorer is interesting and all, but we would rather lose that information (by not logging the transaction AT ALL), than have inconsistent data by entering this transaction without knowing which account the money is going to. Consistency is more important than collecting what data we can no matter what.

On the other hand, if we have a case where a person says, in a comment on a forum, "I like fashion, but not as much as the other", we have incomplete information, but we will still store it. What is the "other" that they like better than fashion? We don't know. But storing the keyword "fashion", perhaps with a positive association, perhaps with an only moderate association because they like something else better, is valuable knowledge (e.g. it may tell us what ads they would be more likely to find interesting). We have incomplete information, but we store it anyway. If the same user said, in another post, "I don't really like fashion", we would store that as well, even though it's inconsistent with the first statement. Incomplete, or inconsistent, is better than not storing it at all, in case 2, whereas in case 1 we would rather store nothing than risk storing something inconsistent or incomplete.

Part of the reason for this difference is related to the "Site is for" difference (see above). In case 1, the user is required to get the information into the system, by their job or for some other reason, and we can demand that it be complete and consistent, refusing to store it until it is. In case 2, the user has no particular need to use the system, we just want them to, so we have to accept what we can get in terms of data completeness or consistency.

An example of the different emphasis, is to compare logging a transaction at work (case 1) with buying something at an ecommerce site (case 2). In case 1, we can require extra information, beyond the bare minimum of account number and dollar amount. For example, perhaps we want to require a category code or project name of some sort to be entered for each lineitem in the purchase. We can, if we want, refuse to log the transaction until this information is given, because we know the user has a need to use the site, and they will persist in entering until they can do so.

In case 2, though, we may prefer to have an email address, or the recipients' gender and age, but we had better not require that, or we will often lose the sale, as the user gives up and changes their mind about buying anything. Even an incomplete purchase, that does not give us the bare minimum (e.g. credit card #) may be stored anyway, so that we can show the user their still-filled shopping cart when they come back, in hopes of persuading them to complete the purchase. In any case, it is useful to know what got put into the shopping cart, even if it never gets purchased, because that can help inform which items are at least getting looked at vs. which items are never being considered. We accept all the information, and store it, whether it is enough to complete the purchase or not, because in case 2, we cannot assume that the user will enter whatever is required to complete the process. In case 2, we prioritize collection over completeness or consistency.

What Developers Want To Convince You That You Need

In many cases, a developer wants to convince their customer (or boss) that what they need, is what that developer is already good at. In other cases, they want to convince their customer/boss that what they need, is what the developer would like to learn about. There isn't necessarily anything wrong with either case, but what the developer wants should only be one of many factors. It is an advantage if the developer already knows how to make what you need; they will probably do it faster, and with fewer mistakes. It is nice, if the developer gets to learn new strategies or architectures; this opens up more options for later projects. But, sometimes, what the developer wants, is not what the customer/boss needs.

Even worse, is where the developer knows that what they should be building is closer to case 1, described above, but their customer/boss requires them to build case 2 instead. I have witnessed this happening, because the supervisor wanted to be able to show the project (which was in fact a classic example of a case 1 project) to outside investors, to convince them that they should invest money. Venture capitalists like to think about case 2, where there are (at least in theory) hundreds of millions of users, and so that is what developers (and their supervisors) will usually be wanting to do. If what they are building is really closer to the case 2 side of the spectrum, there is nothing wrong with this.

But, if what you are actually making is a back-office application to help half a dozen company employees manage their information, in something too complex for a spreadsheet, then both developer and supervisor would do well to admit that what they are doing is more like case 1, and they can get the job done better, with less code and less ongoing maintenance, if they admit that and use the correct tools for that job.

But What About "NIH Syndrome" or "Not Reinventing the Wheel"?

Another argument often used against building a case 1 system, even though the use case is a classic example of case 1, is that we should instead be using a software-as-a-service website that does this kind of thing. In this case, because (presumably) many different businesses are using that website, you get the advantages of many developers supporting it, and also a more "modern" look and feel, even though only a few people in your organization need it, because the cost of those developers (and servers and designers and etc) is spread across many businesses.

Now first it should be acknowledged that this is occasionally the case. But what is often not realized, is that using a general-purpose business app (or website) may not end up being any simpler than creating a vanilla "case 1" website for your own business. The reason is that, in order to allow many organizations to use the same interface, you end up with either:

a) hundreds of options, of which your organization uses 3 or 4, and occasionally the confusion that comes from having accidentally selected one of the hundreds of other options (presumably used by other businesses), or

b) hundreds of settings, to select which of the many ways this application COULD work, is the way in which your business is actually going to use it.

Option (a) is the more common, and it often results in what should be a quick data entry job, instead turning into something for which specific skills are required, sometimes with extensive training. Again, sometimes this is the right choice, but unless you find something that really does exactly what you want, it may turn out to be only sort of what you want, and harder to understand and work with than a custom made, simple version of a case (1) system as described above.

Option (b) is even worse, because what it essentially turns out to be, is that you ARE programming a new custom solution, you're just doing it in a poorly maintained, proprietary computing language, without admitting that it is a programming job. There is no backup, no test environment, no bulletproof way to fall back if a setting is changed and it turns out to have been a mistake. In many of these cases, you end up having to hire consultants to help you set up the application, and they are not any cheaper than developers, because what you are doing without knowing it is hiring a developer to work in a custom (proprietary) environment.

What To Do

Sometimes, the choice is not up to you. Your boss or customer or the other developers on the team are determined to do a case 2 type of system, and you are just going to have to accept that. I make it a point to at least raise the question of whether this is what we really want, but I don't get too worked up about it, and I rarely if ever convince anyone to do the cheaper and better option (for this project), case 1. Ten years ago I might have found this very frustrating, but nowadays I just know that this is the way the world works, and move on.

Occasionally, though, the choice is up to you. Case 2, with large developer cost? Software-as-a-service from some other company, with potentially larger training and consultant cost? Or just make a minimal Case 1 system? Each of these can be correct in some cases, and I am by no means trying to say that you should always choose case 1. What I am saying, though, is that you should be aware that, just as a desktop is better for some work than a smartphone, even though a smartphone is more "modern", it is not uncommonly the case that a server-side architecture ("case 1"), is a better, lower-cost, and more maintainable fit for the needs of your project. Hopefully, with the descriptions above about what each system looks like, you can more easily gain clarity about what type of system works best for each new project.