Chapter 1. The Challenges of Modern Web Development
In technology, any kind of change—even one that’s gradual or starts with smaller projects—won’t be made lightly. These shifts involve evaluation of past investments in infrastructure, acquisition of new knowledge, and thoughtful consideration of feature trade-offs.
So, before we can convince you that there’s value in considering the JAMstack as yet another approach to web development, we’ll spend some time digging into the most pervasive approaches to web development today and the challenges they introduce. Put simply, let’s look first at the risk of sticking with the status quo before diving into the JAMstack and the benefits of making a switch.
The Drawbacks of Monolithic Architectures
Web sites have traditionally been powered by monolithic architectures, with the frontend of the application tightly coupled to the backend.
Monolithic applications are opinionated about how tasks on the server take place. The opinions they enforce have shaped how web development is approached and the environment within which we now work.
Popular and trusted as the de facto way to build for the web, these tools have had a profound impact not just on how sites will perform, but also on how efficiently they can be developed and even on the mindset of the developers.
The lock-in created by this is tangible. These applications dictate the approach to many facets of a web development project in ways that are not always appealing to the web development community at large. The selection of one monolithic app over another is often based on how long their lists of features are. A tendency to select tools based on what is best in class, or the most popular in the market, can often overlook a fundamental consideration: what does this project actually need?
So, does this sound familiar? Have you worked on projects where what should be simple is actually rather complex? Perhaps this complexity has been accepted because the project is for a high-profile site or being worked on by a large team?
Does the complexity you encounter feel truly necessary?
By regularly asking ourselves these questions, we have come to believe that there is a level of overengineering present in web development today. This overengineering impedes the use of proven, effective processes, technologies, and architectures.
Can we take action to improve this situation? Can we attack the limited flexibility, performance concerns, scaling challenges, and security woes imposed on us by legacy architecture?
The freedom to do good work—to design the exact experiences we want for our users—is regularly compromised by complex monolithic applications.
Over the past few years, there has been a rising appreciation of the dramatic performance gains made by optimizing frontend code. Yet, while recognition of the value of strong frontend development has grown, the platforms developers use have often not afforded the freedom to bring frontend skills fully to bear.
The architectures imposed by monolithic applications can undermine our ability to utilize the latest technologies and even affect such things as our development workflows. This inhibits our efforts to fundamentally protect important aspects of software development such as a healthy development experience to unlock the potential in our talented development teams.
Website performance is integrally important to the success of internet-delivered content. Many studies exist that conclude that performance and conversion are tightly linked. One such study concluded that a single-second delay in load time can hurt the conversion of an ecommerce site by 7%.
As it happens, monolithic apps are rarely conducive to superior site performance. They need to generate and deliver HTML every time a new visitor arrives on the site. This significantly slows down page load time.
But performance isn’t dictated by speed alone. Because monolithic apps are so large, it can be difficult to define architectural boundaries. The code is so interconnected that fixing a bug, updating a library, or changing a framework in one part of the app can break another part of it.
Caching is another important part of overall site performance—and it’s one that’s notoriously difficult to get right with a dynamic site. If a site is built on a monolithic app, it’s possible that the same URL can return different content depending on a variety of parameters, including whether a user is logged in or the site was previously running a split test. Being able to deliver a predictable experience to end users is vital.
Because monolithic architecture requires the page view to be generated for every visitor, infrastructure needs to be scaled in anticipation of site traffic. Not only is that expensive, it’s also difficult to get right. Teams end up over-provisioning their infrastructure to prevent downtime or risk a crash because there is no clear separation between the infrastructure required to generate and manage the site and that required to serve the site.
When the same application that builds the page views or lets authors manage content also needs to be scaled to handle traffic spikes, it’s not possible to decouple these facilities in order to scale and protect each piece of the infrastructure according to its needs.
In this scenario, the considerations that influence the technical architecture of a site suffer from being lumped into one large system. In computer science, we recognize that the costs of writes and reads can be very different, and yet monolithic apps bundle these features together into the same application, making them difficult to design for appropriately.
The approach to designing a system that allows for hundreds of millions of read operations is very different to that of a system that allows a similar number of write operations. So, is it wise to combine these capabilities into the same infrastructure and demand that the risk profile of one feature influence that of another? And are those features likely to encounter similar traffic levels?
There are ways to put distance between the users visiting your site and the complexity that generates and delivers that site. Without such separation, scale can be difficult to achieve.
We want to ensure that as we’re evaluating the reasons that monolithic apps are no longer serving the growth of the web, we’re careful not to insult the hundreds of thousands of development teams that chose to implement them. We’ve been that team. You might be on that team right now. One of the ways to avoid this is by simply looking at the facts. And when we talk about security, the facts are difficult to dismiss.
According to recent estimates, Wordpress powers 29% of the web. Joomla and Drupal follow as the second and third most popular content management systems, respectively. That makes them a prime target for bad actors.
The availability of these products as hosted services can help to absolve us from some of the responsibilities for securing the underlying infrastructure, but in self-hosted instances, we must shoulder all of that burden ourselves. In either case, there are many attack vectors, and the introduction of third-party plug-ins can expose us to further risk and make things even more difficult to secure.
Monolithic apps like Wordpress, Drupal, and Joomla combine every single component and plug-in of a web project’s architecture into a single codebase. In turn, it creates a massive surface area for malware to penetrate. Not only is the attack surface area extremely large, it’s also exposed every single time the site is built because any plug-in the site uses must execute each time the page loads for a new site visitor, magnifying the risk.
With that volume of distribution, injecting malware into a single plug-in can mean massive distribution. A recent attack caused 12 million Drupal sites to require emergency patching.
And there’s one more gotcha: in monolithic apps, plug-ins are tied directly to the core framework. Because they’re notoriously insecure and require frequent (and often buggy) updates, hastily updated plug-ins run the risk of breaking the entire site. Maintainers are left to choose between security patches and the risk of breaking site functionality.
The Risk of Staying the Same
Developers and business decision-makers alike have recognized the risks of continuing to develop web projects using monolithic apps. But the risk of change often outweighs the risk of staying the same. For large companies, massive investment in architecture and talent combines with fear of giving up the flexibility, features, and tooling of a more mature ecosystem. For small businesses, rebuilding web infrastructure pulls resources away from critical growth initiatives.
However, it’s our belief that the time has come when continuing to invest in the status quo is a risk too great to perpetuate. And there’s an army of developers who are backing this up. The first whispers of change came as a wave of personal blogs, open source project documentation sites, and time-bound projects like events and conference sites migrated to the JAMstack.
These whispers have grown louder as larger sites with greater audience numbers and more content also began embracing the JAMstack, challenging previously accepted limitations by delivering comments, subscription content, ecommerce, and more.
As more of the world’s population comes online, it’s essential that we deliver sites that can handle huge traffic spikes, perform quickly and predictably under any traffic conditions, support different languages and localizations, and be accessible and usable on all the devices we know and many that we don’t. And, sites need to do this all while being secure and protected from the malicious attacks that are inherent in an open, global network.
This sounds like a job for the JAMstack.