As web developers, we’re always evaluating the tools we use to build the internet’s vast and varied landscape. The decisions we make in selecting these tools have major implications—not just for our work’s immediate outcome but for its long-term sustainability and our own sanity. In this exploration, I’ve taken three different approaches to building web applications: React, AJAX, and good old plain HTML, and built three versions of an app that you can try yourself. But don’t think of this experiment as a three-way shootout; it’s meant to be more of a Rosetta Stone, to help organizations understand when and why they might choose one path over another.
This post, then, is for those who stand at the crossroads of technology choices, whether you’re a manager, a developer, or just someone interested in the web’s workings. It’s a dive into the practicalities of web development technologies, with real-life and real-time examples that you can dig into, not a polemic. React has its place, as do AJAX and plain HTML. But understanding the terrain can help you make better decisions, whether you’re building a quick prototype, a complex application, or anything in between.
HTML sets the basic structure and content of web pages.
Javascript enhances web pages with dynamic interactivity and functionality.
AJAX, a technique using JavaScript, updates parts of a web page without reloading the entire page.
React is a powerful Javascript library for building dynamic and complex user interfaces with reusable components.
The Experiment
The chosen app* is straightforward enough for a single developer to build three times without excessive effort, yet complex enough to reveal the strengths and weaknesses of each approach. The core functionality—adding, displaying, deleting, and toggling tasks—remains as consistent as possible across all three versions. What changes is how each version’s frontend handles user input and updates the UI. In the next sections, I’ll break down how each version was built, what it was like to work with each technology, and how they stack up in terms of performance and user experience.
The app in question is a simple scheduler, Appt Keeper. It allows users to add, delete, and mark appointments with a reminder. Though seemingly elementary, it encompasses core functionalities common to many web applications: CRUD operations (Create, Read, Update, Delete) and a measure of UI dynamism. The backend for all three versions is a collection of shared PHP scripts, serving as an API that interacts with a MySQL database. This ensures that differences in user experience stem solely from the frontend technologies employed.
Plain HTML: The Underestimated Workhorse
Starting with plain HTML, the development process is as straightforward as it gets. You write your HTML, style it with CSS for visual presentation and interactive pop, and sprinkle PHP where necessary for dynamic content. It’s the bedrock of web development, accessible to beginners and seasoned developers alike. The lack of build processes, transpilation, or dependency management makes it extremely approachable. Modifications are a breeze; you simply change the code and refresh your browser. For many projects, especially those without complex interactive requirements, this approach is more than sufficient.
AJAX: Bridging the Gap
Asynchronous JavaScript and XML (AJAX) stands as the middle ground, offering a way to update the page dynamically without reloading. Using vanilla (hand-coded) JavaScript, you can fetch data from the server and manipulate the page structure or DOM (Document Object Model) based on user actions. It’s slightly more complex than plain HTML but far less so than React. AJAX allows for an interactive user experience without the overhead of modern JavaScript frameworks. However, managing DOM page elements and maintaining UI consistency becomes more challenging as application complexity increases.
React: The Modern Juggernaut
React represents the new paradigm of JavaScript frameworks, but with that comes complexity and a completely different approach to page building. Setting up a React project means navigating the world of NPM, Webpack, Babel, and JSX. React shines in its ability to create modular, reusable components and manage application state in a scalable way. The virtual DOM optimizes rendering, making it a strong choice for highly interactive or complex applications. This capability, however, incurs costs in terms of intricate setup, a steep learning curve, and a build process that’s integral to both development and deployment.
Comparing Development Experiences
When comparing the development experience across these technologies, a few points stand out. First, the simplicity of plain HTML is refreshing (though I will admit getting that form toggle to work without JavaScript was a bit of a hack). There’s a directness to writing code that immediately affects what you see in the browser. The same is true of an AJAX page, except that working with the DOM can be a muddling experience leading to expressions of the type, why isn’t this working?! React, by contrast, abstracts much of this away in favor of a componentized architecture and state management. This abstraction is powerful but can feel detached from the “direct manipulation” ethos that characterizes traditional web development.
Performance and Maintenance
While all three approaches can yield fast and responsive applications, the key to performance lies more in the quality of the coding than in the choice of technology. React’s component-based architecture arguably makes it easier for a team to maintain and update large applications, provided they’re well-versed in React. AJAX and plain HTML can become unwieldy as the project grows, unless carefully organized.
Choosing the Right Tool
The choice between React, AJAX, and plain HTML isn’t about which is better in the abstract. It’s about which is right for your project, your team’s skill set, and your long-term maintenance plans. For small projects or those with limited interactivity, plain HTML or AJAX might be all you need, or at least, all that is needed to start. For more complex applications, the modular architecture and state management capabilities of React could be worth the investment.
Loading Time and Responsiveness
First impressions matter. For web apps, this often boils down to how quickly the first usable content appears on the screen. The plain HTML version of Appt Keeper, unsurprisingly, shows its strength here—its simplicity translates to speed. There’s no hefty library to load, no virtual DOM to calculate, just straight-to-the-point delivery of content.
AJAX introduces a bit more complexity, but it’s still pretty lean compared to a full-fledged React app. The AJAX version of the app feels snappy because it requests only the data it needs, when it needs it. However, the initial load time doesn’t differ significantly from the HTML version, as the real differentiator is in the dynamic content loading after the page is already up.
React, with its virtual DOM and component-based architecture, shines in user experience once the app is loaded. The initial load might take a tad longer due to the size of the React library and additional JavaScript, but subsequent interactions feel seamless. The virtual DOM’s diffing algorithm ensures that only the components that need updating get touched, making the UI very responsive to user actions.
Try The App
To see how the Appt Keeper performs across different technologies, I suggest comparing the three versions side by side. Use these links to pre-load each version with fresh appointments for you as the user, preferably in Chrome’s Incognito Mode (right-click the links below for the option) to ensure that browser extensions do not interfere with the test:
React Version:
https://www.keithmoulton.com/react/refresh.php?style=react
AJAX Version:
https://www.keithmoulton.com/react/refresh.php?style=ajax
HTML Version:
https://www.keithmoulton.com/react/refresh.php?style=html
Before diving into the metrics, let’s consider if there’s any noticeable difference in user experience across these versions. As you test, notice not just the speed, but how each version handles user interactions—does one feel more ‘snappy’ or responsive to your inputs than the others? The app handles five key interactions:
- Form Toggle: A Close/Add button hides or reveals the form.
- Save Appointments: Users can add new appointments to the list.
- Reminder Toggle: By double-clicking (or a single click on the HTML version), users can toggle reminders for appointments.
- Delete Appointments: Click the red X to remove from the list.
- Reset List: The RESET link clears the current appointments and loads default entries.
To assess performance, open Chrome’s Developer Tools, and select the “Network” tab. Reload and interact with each version, noting load times under various conditions such as normal and hard reloads (read how). Key metrics to watch include the cumulative Load time and DOMContentLoaded times at the bottom of the Network tab.
For simple broad reports, go to the “Lighthouse” tab, and “Analyze a Page Load” in mobile and desktop configurations. Here are some results:
Version
Performance
Speed Index
React
98
0.5s
AJAX
100
0.5s
HTML
100
0.2s
After repeated tests, it should become clear that all three versions perform very well, usually responding in well under half a second. As one might expect, the performance of the React version shines with cached resources, while the AJAX and HTML versions seem to edge out the JS framework when the cache is clear. This observation suggests that, in some cases, the simplest HTML version might be the quickest, but feel free to play around with each app—you may find the HTML version doesn’t work quite as well on mobile devices.
Let’s also take comparative look at the codebase size and file count for each of three apps. While all versions share five PHP scripts that constitute 255 lines of code, the additional code required varies significantly:
Plain HTML Version: 118 lines (plus backend API).
The most straightforward, consists of 1 main PHP file that combines HTML, CSS, and PHP code.
AJAX Version: 148 lines (plus backend API).
Offers greater interactivity, consists of 1 main PHP file that includes HTML, PHP, and JavaScript.
React Version: 251 lines (plus shared files).
The most complex, contains about 25 separate files, mostly JavaScript.
[Full file and code detail]
Plain HTML Version: (No JavaScript)
index.php: 118 total lines of html/css & php:
(56 lines of PHP +11 lines of extra CSS)
AJAX Code Version: (Vanilla JavaScript)
index.php: 148 lines of html, php, JavaScript:
(25 lines of PHP + 78 lines of JavaScript)
React Code Version: (React JavaScript Library)
PRODUCTION (All shared files above, plus:)
fetch_tasks.php – 24 lines
index.html
main…css.map
main.css
main…js.map
main…LICENSE.txt
main….js
787…chunk.js.map
787…chunk.js
logo192.png
logo512.png
robots.txt
manifest.json
asset-manifest.json
DEVELOPMENT SRC (Not including Production items)
AddTask.js – 47 lines
Button.js – 24 lines
Header.js – 20 lines
Footer.js – 13 lines
Task.js – 16 lines
Tasks.js – 18 lines
App.js – 72 lines
index.js – 17 lines
TOTAL – 227 lines of custom JS
ADMIN (Auxiliary files)
reportWebVitals.js
package-lock.json
package.json
README.md
.gitignore
node_modules folder
Shared Code in all 3 apps:
PUBLIC SIDE:
favicon.ico
index.css (React version is compressed)
SERVER SIDE API SCRIPTS:
main.php – 110 lines
add_task.php – 45 lines
delete_task.php – 27 lines
refresh.php – 45 lines
remind_task.php – 28 lines
TOTAL: 255 lines
We can see from these statistics that React doesn’t present a marked advantage over AJAX or basic HTML for our sample app. The user experiences across the technologies are remarkably similar, and both AJAX and HTML require significantly less code. However, it’s important to note that React’s benefits become more apparent as a web page’s interactivity and complexity increases, and our modest app does not play to React’s strengths.
Take Yahoo Finance as an instance where React’s power is evident, updating prices and charts in real-time without page reloads. Facebook, which developed React, offers another prime example, although in my opinion, Facebook’s web interface has its drawbacks. This discrepancy may stem from the challenge of aligning its web and mobile app experiences, highlighting the considerations of using JavaScript frameworks for cross-platform coherence.
Maintaining compatibility across different devices—web and mobile—plays a significant role in the decision to adopt a JavaScript framework, potentially easing the burden on developers. However, as organizations grow, governance and decision-making processes can also significantly impact user experience, sometimes more so than the underlying technology.
An intriguing discussion on Reddit provides further insight into this issue, theorizing that Facebook’s UI shortcomings may stem more from corporate governance than technical limitations. This highlights an essential aspect of web development: technology choices are often deeply intertwined with organizational structures and priorities.
The JavaScript Wave
JavaScript frameworks have become an increasingly significant part of web development since 2010. This growth may be in part due to the influence of programmers raised on mobile app development (which shares similarities with JavaScript-driven web development) and the emphasis on stateful, object-oriented programming in computer science programs, which some grads might find analogous to the component-based architecture of frameworks like React. Traditional web development, on the other hand, relies on a stateless architecture and more procedural approach, with a natural separation between HTML and CSS on the frontend, paired with a server-side scripting language like PHP and database on the backend.
The Honeypot documentary on the history and development of React provides excellent insight into understanding why the engineers at one of the most powerful and well-funded tech companies paradoxically felt that their React project was an “underdog technology” as they pushed back against web development orthodoxy inside and outside the company.
The takeaway I got from watching the documentary was not that their framework should be considered proven technology for other organizations to use. Rather, my conclusion was that companies whose core business involves software engineering should really consider coding their own solutions and rely on themselves to figure out what will work best for them. It is not clear to me why so many businesses feel the need to place their entire tech stack on the whims of an open source community that is largely driven by Facebook’s needs and wants.
The appeal of React and similar JavaScript frameworks largely stems from their ability to dynamically update the user interface without requiring a full page reload. This makes for a smoother, more app-like experience on the web. However, this doesn’t come without its costs, particularly when we consider the broader implications of adopting such technologies for web development projects.
Weighing The Complexity of React
Virtually everything you can do with a JavaScript framework like React can also be achieved with vanilla JavaScript, and nearly everything else with plain HTML and CSS. Frameworks may offer marginal UI performance improvements and help in dividing tasks among a team, but they introduce their own set of challenges, such as search engine optimization (SEO) and software dependencies. Of course, the React ecosystem is always growing new capabilities, such as the server-side Next.js framework and React Server Components, that help to address such issues, however, each new innovation brings more complexity to the developer’s desktop.
React, and by extension, Create React App (CRA), forces a paradigm shift in how applications are developed, deployed, and maintained. The component-based architecture, while modular and organized, necessitates a build process that compiles these components into a deployable application. This process, while streamlined by tools like CRA, introduces a layer of complexity foreign to traditional web development practices.
For instance, the inability to deploy “hot fixes” or single file updates without undergoing a full rebuild and redeployment process can be seen as a step backward in operational agility. In traditional web development, particularly with server-rendered applications using AJAX or plain HTML, updates can be more granular, often requiring nothing more than uploading a revised file to the server.
Moreover, the dependency on a build system and the need to navigate a complex ecosystem of tools and libraries to maintain a React application introduces a form of technical debt that is not as prevalent in simpler AJAX or HTML/CSS/JavaScript projects. This debt manifests not only in the cognitive load on developers to stay abreast of the ever-evolving React ecosystem but also in the potential for reduced flexibility in responding to immediate needs or issues that arise post-deployment.
Snappy Interfaces, Sluggish Pages
This discussion is not to diminish the value React brings to the table, especially for applications that benefit from its state management and dynamic UI capabilities. However, it’s crucial to weigh these benefits against the operational and maintenance overhead they introduce. For many projects, especially those not facing the scale of challenges that a Facebook or Netflix does, the traditional web development approach, leveraging AJAX and plain HTML, might offer a more straightforward, cost-effective solution.
The crux of the move towards JavaScript frameworks and AJAX-driven applications lies not just in their ability to create dynamic, responsive user interfaces (particularly on small mobile devices) but also in fixing the sluggishness of modern webpage loading. The goal of web development has always been to provide users with fast, seamless experiences but as time goes on this principle seems honored more in the breach than actually observed. Ideally, a webpage should become functional within just a second or two, with anything beyond a three-second load time risking user engagement and satisfaction.
The delay in loading webpages today often stems from the excessive burden of unnecessary code and resources being loaded upfront at the server level. It is not unusual, for example, for a WordPress or Drupal website server to load 25-50mb into memory for each and every page load. This bloated approach hampers performance and underscores the importance of efficient coding practices. By streamlining the resources each page requires and optimizing for quick loads, we might mitigate the need for complex JavaScript solutions to speed up user interactions.
Conclusion
In summarizing our comparison, each method emerges with its own set of strengths, limitations, and uses. From the simplicity and directness of HTML to the sophisticated state management and component-based architecture of React, each approach offers unique benefits suited to different project needs.
I encourage readers to explore the three versions of the app for themselves, examine the source code, and comment below (moderated solely to filter out spam). Hopefully, together we’ll gain a deeper appreciation for the variety of web development tools at our disposal and the importance of selecting the right tool for the job.
*Acknowledgment to Brad Traversy:
The frontend portion of the React version of the app highlighted in this analysis was inspired by Traversy Media‘s excellent crash course video on React. For those wanting to understand the build process behind the React version’s UI, Brad’s tutorial guides users through each step of setting up a development environment and piecing together components into a working application.