A Brief History of Web Development

A Brief History of Web Development

How we got to SPAs, RSC, Remix and why this is all important

The most thrilling days of web development are happening now. We have access to the best tools, making website and web app development an unparalleled experience. Faster, more efficient solutions are being developed monthly, causing the entire field to evolve like there's no tomorrow.

But it hasn't always been like this.

About twenty years ago, when I made that first website for the kindergarten where my mother worked, the coolest thing was the marquee effect – that I just recently learned has been deprecated. 💔

Meet Macromedia Dreamweaver, where web development started for me:

Macromedia Dreamweaver 8 Free Download + Serial - Software Free ...

But once I figured I could not only drag and drop things on the canvas, but there's this HTML view, and some say there's even a PHP server somewhere that can manipulate and store data, there was no going back.

This is where my history of web development started.


I considered PHP as an extension on top of HTML altough this wasn't completely true.

I could already create mindblowing static sites using the right amount of marquee (RIP 💔), but tapping into a data source on the server made me feel like Neo.

<!DOCTYPE html>
    $sql = "SELECT username FROM users WHERE id = 1";
    $result = $conn->query($sql);
    echo "<h1>Welcome, " . $user_username . "!</h1>";

I'm not sure if this is how PHP looks today. Hashnode's AI code generator gave this to me, and it certainly looks like something I wrote!

Using this tech, I built my first SaaS right before the year I went to the university. It was a phpBB-like forum for our middle school. Using the same stack, I wrote an even bigger app used as a nationwide registration system for a national mathematical competition.

I didn't know what SaaS or being productive as a programmer meant back then because I just dabbled with these things.

15 years later, it's an absolute yes. HTML, CSS, PHP, and MySQL made me extremely productive. And I haven't used JavaScript at this time. I used maybe snippets I found on the internet, but I showed no interest in learning it because I didn't need it.

The apps I've built in those years mostly looked like current government websites:

Website Forms Usability: Top 10 Recommendations (2023)

Remember clicking that submit button a couple of times?

Ajax responses, the first spinners

It didn't take me long to realize the value of Ajax. Suddenly, I didn't need full page reloads to show dropdowns with different values or to disable a Submit button when the request was already processing.

Ajax improved the user experience by adding a slight cost to the maintenance.

At this time, most of my applications were still 99% PHP, HTML, and CSS. Fast forward 4 years to my graduation.

I learned a whole lot of Java at the university and continued selling websites as a side hustle until I landed my first developer job in January 2012.

JSF (Jakarta Server Faces) was popular then, and the company I worked for was bullish on enterprise Java.

Looking at you, ReponseTaskServerAdapterPropertyObserverSetter.

We built web apps that looked like desktop apps, which were incredibly painful to develop, deploy, and maintain.

They looked like this:

Código Fonte Blvendasee 1.0 Java Para Web Jsf Primefaces Jpa - R$ 89,00 ...

JSF wanted to be a silver bullet; we didn't use much pure HTML because JSF libraries had components for buttons, inputs, autocompletes, etc. But it was a world full of promises and a horrifying development experience.

The SPA revolution

SPAs came like a savior.

Once we realized we could expose REST APIs on the server and write our entire client in JavaScript, our productivity reached HTML, CSS, and PHP levels again.

The client apps resembled what you would have today in a React application.

// bundle.js
var message = new Message();
var messageView = new MessageView({ model: message });


// index.html
<html lang="en">
    <div id="root"></div>
    <script src="/bundle.js"></script>

A nothingburger and a client app packed into a ginormous bundle.js file.

The bundle got to the client, but it had to fetch some data to render the app first.

And this is when our apps started to have more of these:

The Spinner Hell

But it was not just the spinners. This client-rendering behavior introduced a whole lot of other issues, like layout shifts:


The bundle sizes got out of control unless you were really, really careful. You could have gzipped a date library that added 50kB to your bundle size when you could have converted the timestamp from the db into a human-readable format before sending the response!

Websites felt slower, but the spinner kept spinning, giving us some hope.

RSC, Remix

Up until now, we simply didn't have better ways to deal with this problem other than maybe using UI skeletons. They weren't a perfect solution either, and they looked weird when they got out of sync with the rest of the app.

How to Build a Skeleton Layout in React - DEV Community

React Server Components are an idea to tackle this problem with an initial implementation, but not much acceptance from the community yet.

Ryan Florence wrote an excellent blog post about the key differences, both in theory and in practice, between RSC and Remix in React Server Components and Remix.

To sum up, React Server Components follow the Render-Fetch waterfall. This means the component gets rendered first and then it fires a fetch.

In contrast, Remix uses the Fetch, Then Render waterfall, which is closer in behavior to what we had before the spinner armageddon.

Remix's loader does all the fetches, and when they're ready, only the result (component populated with the result of the loader) is returned to the browser.

Remix acts like an SPA on subsequent navigations and fetches only the necessary data to show the view.

See what happens after I switch between /me and /settings:

Hitting /me for the first time, retrieves the simple HTML page already pre-populated with the data – no need for loading spinners.

Kind of like in:

<!DOCTYPE html>
    $sql = "SELECT username FROM users WHERE id = 1";
    $result = $conn->query($sql);
    echo "<h1>Welcome, " . $user_username . "!</h1>";

But switching back and forth between the /settings and the /me page fetches only what's necessary – a JSON containing the data needed to display /me.

Why this changes everything

Instead of going with the overused "Next.js is PHP now" memes, I want you to think about where it all started and how far we've come.

This is an evolution.

It's all about constantly changing, trying new things, keeping what worked, and leaving behind what didn't.

From marquee 💔, PHP/HTML/CSS, to JSF, and the painfully slow deployment times that made web development with Java an absolute nightmare, back to a much simpler render request-response cycle.

Today, we can pick from the best tools the industry offers.

They all provide a lot better development experience than I could have imagined 20 or 10 years ago.

Congrats to the Next.js and the Remix teams for their fantastic job and community support.

I hope the React team will finalize the RSC Next year and everyone can use it to their fullest potential to build even better apps.

Did you find this article valuable?

Support Ákos Kőműves by becoming a sponsor. Any amount is appreciated!