Tuesday, October 25, 2016

JavaScript for the whole application? The case for

This post makes the case for building the whole application, both on the client and server, using JavaScript. In part one, we looked a the case against using JavaScript for building the whole application especially for large projects. In this post I'll take the opposing view and present the case for why using JavaScript for building the whole application can bring significant benefit to development shops.

Reducing Development Costs

Many organizations have used JavaScript on the server via Node for specific use cases like implementing Web APIs and realtime communication using WebSockets. These implementations have benefited from Node's asynchronous event processing capabilities. However, today this is not a huge benefit as other popular languages have quickly added easy-to-use asynchronous capabilities. Some even say that Go is a better language than JavaScript/Node because it easily utilizes all server CPUs without being forced into isolated processes, supports more threading and asynchronous scenarios, handles errors gracefully and compiles code to native platform executables.

One could cite server platform neutrality and this again would be an ordinary benefit but not a major benefit. Other languages like Java and the open source languages like Go, PHP, Ruby and Python already support multiple platforms. Certainly languages that are not platform neutral will be at a disadvantage in the future as more organization move to cloud-based computing and want to keep their options open with respect to cloud provider choices.

A major benefit would be using a single language for client and server development especially if mobile clients are included using frameworks like Apache Cordova or React Native which permit mobile application development using JavaScript. Consider having to only hire JavaScript developers versus having to hire Java developers for Andriod, Objective-C developers for iOS and Ruby developers for the web. It's not just the cost of the developers but the the cost coordinating, testing and maintaining a lot of the same functionality across different languages. Keeping application logic and test scripts in sync across different languages requires a huge effort compared to using a single language for development. Having the ability to reuse code for different clients and the server in the form of shared models and JavaScript libraries can result in significant cost saving for any size development shop.

Reducing Computing Costs

A consequence of being able to use a single language for both the client and server is the ability to shift more of the processing to the client. Today, there's still a lot of processing taking place on servers that can be shifted to the client. Over the years web applications have moved away from complete page reloads to using AJAX requests for carrying out application operations. However a good deal business logic especially calculations and validations are still carried out on the server that could also be taking place on the client.

Consider a simple business calculation such as multiplying hours by hourly rate to get a billable amount. This calculation can be implemented as an API on the server and made accessible via API requests from clients. The benefit of this approach is a single code-base for how this business calculation is carried out. Should the calculation get more complicated - such as applying overtime rules or currency conversion - then all the code for doing so is hopefully implemented in one language albeit on the server only.

This type of business processing may not have anything to do with how things are validated and stored on the back-end. It could be just a different view or an aggregation of the data. For example, a project manager may create a project budget by entering resource hours by day but is able to see total budgeted costs in dollars for the whole project or time-phased by day, week or month. The data validated and stored on the server is resource hours by day and yet calculating the budget cost in dollars requires the use of various lookups and applying business calculation logic.

Having this type of processing carried out on the server every time the project manager enters or changes a single value in the project budget can needlessly consume server resources and network bandwidth, and often results in a poor user experience. The alternative - implementing this model and associated calculation logic for different clients in different languages and all the required unit tests and Q/A test scripts - would be very close to the effort of developing entirely different applications. Both the client and server should be capable of carrying out the processing when needed. The client for example can perform this processing when the project manager is entering or modifying the budget and the server in turn may need to generate a scheduled PDF report of the same project budget in dollars by month at some later date.

In the enterprise there are many such types of applications: budgeting, resource planning, project scheduling, time sheets, expense reports, portfolio planning, billing, loan amortizations and so on. Practically any spreadsheet-like or time-phased buckets application where the user enters or changes a value that has the potential to affect or calculate many other values based on business logic falls into this category. Even a consumer SaaS applications such an online personal tax return filing service that displays the tax refund amount on the screen as the user enters various tax related values will need to perform this type of business processing. Cloud computing providers greatly benefit when all this processing is kept on the server because it increases their revenue. SaaS vendors that deal with hundreds, thousands or even millions of customers on a daily basis can incur significant costs that could otherwise be avoided by simply shifting more of this type of processing to the client.

Applications with spreadsheet-like editing functionality usually work best when processing takes place on the on the client because each user is assigned their own dedicated local CPU and memory, and network requests are minimized. However, today many architects spend a great deal of time coming up with elaborate strategies used to minimize the latency of performing these calculations on the server. One way is to use a distributed caching service to quickly load a large model in memory, perform the calculations and return the results. There is also the option of keeping a live server connection open possibly using WebSockets and keeping the model active in server memory. There are many strategies and scaling techniques but the end result is more server or cloud computing resources will be required. It would be better if both the client and the server are capable of performing this type of processing and the decision on where this processing takes place is not dependent on the implementation language but on where it is best to have this processing take place.

A development shop could attempt to create its own unique business language that can run locally under different platforms. However, this will be a large undertaking and is usually beyond the core competency of most IT shops. A better approach would be to use JavaScript which is already supported by web browsers, mobile platforms and servers. No other language enjoys this much ubiquity and taking advantage of it can results in significant development and production cost savings.

Conclusion

In the heyday of mainframe time-sharing days, organizations used different techniques to save money on their computing costs. Techniques such as applying resource quotas, restricting the number of logged in users or shifting job processing to non-peak times reduced computing costs. Some even sold their excess computing capacity at reduced rates to third parties in an effort to save money. Today, cloud computing providers have mastered the art of billing for everything like the number of disk reads/writes, memory usage, disk storage, network bandwidth, cache requests, database transactions, category of CPU, time of day and a slew - sometimes hundreds - of different services. Pricing is often quoted in pennies or fractions of pennies but the bills come in hundreds and thousands of dollars. As cloud computing costs become a significant part of the total IT budget, developers and architects will be forced to become intimately familiar with their application computing needs and make every effort to reduce these costs.

Developing in JavaScript and shifting more of the processing to the client can reduce cloud computing costs and increase responsiveness. However, two things need to happen before building whole application in JavaScript can take place. First, organizations want something that competes with their industrial strength modern typed server-side languages they currently use. Second, ironing out the inconsistencies of how developers code with JavaScript on the client versus the server (e.g. loading modules).

There are already various efforts trying to unite Node and browser development by supporting similar techniques (e.g. module loading) and consolidating various core libraries (e.g. URL, HTTP, Path, etc.). EMCAScript 2015 and continual evolution of JavaScript is also another piece of the puzzle. If in fact Ecma hits a yearly release schedule and more enterprise features like those found in TypeScript are put into JavaScript then this shift to moving more of the business processing to the client will accelerate. It is even possible that as JavaScript evolves popular server side languages like PHP, Ruby, Python, C# and Java will diminish in popularity over time.

No language is perfect and certainly JavaScript has a lot more deficiencies and shortcomings than many other languages. Most server-side languages have evolved over time to address their own deficiencies. Often this results in a mishmash of old and new. Compatibility with existing code and libraries is always a problem when a language evolves. JavaScript is no exception. In fact it's even more so with JavaScript given that the language is not implemented by any single organization or open source effort. Introducing new features in JavaScript requires more time than other languages because it requires a great deal of consensus from many players around the globe. Breaking the web is not an option.

Architects waiting for the perfect client and server language to emerge are simply waiting on a pipe dream. One of the best efforts attempted with significant resources and financial backing was Java. Java was and still is a success on the server and to some extent on native cross platform desktop applications but it fizzled quickly on the web. SilverLight, .NET and C# was also another attempt but that too fizzled out. Even Adobe gave it shot with Adobe Flex with similar results. On the web, the mindshare is with JavaScript and it is unlikely that will change any time soon.

JavaScript is not necessarily the best language for large-scale development and its shortcomings and issues are well documented. However, that should change over time as JavaScript evolves. The benefit of using JavaScript lies in the cost savings of using a single language for development and the cost savings of being able to shift more of the processing to clients.