A brief history of web development, and why your framework doesn't matter
gebna.gg
gebna.gg
It’s strange to me that one can be a webdev without understanding that you do not need JS for a web app, although it does improve the UI in some areas.
It feels even stranger that the term server-side rendering became a thing, since the server doesn’t render anything, but just generates HTML and sends it over the wire.
And I’m only 39.
Render is the final step presented to user. Users do not see HTML, they see text, boxes with background colors, buttons, those are html elements rendered for visual consuption.
The rendering you mention never happened anywhere in the React JS code. Browser did the rendering internally.
Web is much more than the React "ecosystem".
from js class to dom objects => pre render 1 from dom to html => pre render 2 from html to display graphics => final render
I work with frontends among other things so I am semi-aware of the current state of insanity.
I try to not talk too much and go with the flow. The older I get the more software (and business) in general seems like it’s built out of raw insanity.
I started working post Ajax using jQuery using Java JSP’s (2010).
Back then, I believed that the people making this argument were onto something, as it felt overly complicated to me as a beginner.
At this point it feels more likely that the people making this argument don't have any kind of experience in frontend development that span multiple teams collaborating on the same UI.
In the backend this was "solved" through mocroservices. In the frontend you're gonna be in a world of pain unless you're using one of the popular spa frameworks. Well, you're probably still gonna be in pain. It'd just be worse if you didn't use the framework.
Times were simpler then, I feel the abstraction was a lot simpler.
I'd like to see the simpler ColdFusion / ASP style model grow with support from smarter back end tech.
The crazy levels of abstraction in the client/server model are just confusing for someone like me, who was quite happy with the older way of doing things.
Web delivery should be about simplicity and maintainability, not seemingly academic exercises in purity, speed, or abstractions.
Well, that's the catch. If you are building marketing web _sites_, then maybe. I made my first website in 1999. But sites never entertained me much, I preferred building apps.
I've even built my first web _app_ using plain JS. It was quite painful. When jQuery came around, it was a miracle. But still, building dynamic forms with dependent fields, multi-step forms etc was quickly becoming chaotic. I was basically doing my own version of htmx, this was sth around 2006. You could theoretically keep some semi-sane architecture with jQuery and server-generated snippets but it rarely happened in reality.
Enter Backbone. Finally some good code organization for frontend code. A bit of boilerplate, some pandemonium of events in large apps. Still fond memories and pretty solid apps.
When I first saw React I was appalled. What is this ugly XML thing with code inside? That's like php at the turn of the century. But then I've never really liked any templating language so I gave it a try and never looked back. React is going through some weird identity crisis, but I would still pick it up for any serious enterprise dynamic web app. I have high hopes for Solid, which should be React but cleaned from some historical mistakes. But for sure I am not going back to stitching some server generated snippets and quickly hitting it's limits.
I didn't forgot about server generated html. It's fine for a _lot_ of web pages. But let's not pretend that this is some universal goodness. It sucks for dynamic experiences. Htmx is not our lord saviour, it will again quickly become a mess with stringly connected bits and pieces. Just a simple form where sometimes you need to return the forms with errors or successfully update some elements elsewhere: you need to use ugly out-of-band updates. They tout Htmx being the true REST but handling 400s is shit, now you're adding some events and lo and behold, you are back where I was in 2006 with tangled ball of strings.
(I'm also 39. You and I may see each other at the shuffleboard court soon.)
Meanwhile, someone somewhere is working on a backend framework that streams raw display frames to a lone <canvas> element.
Also more recently, the increasing push for moving everything - from CSS declarations to server-side actions - into components. This gets a brief mention, but again, it's one of the ideas that best explains recent trends in frontend development (and many historical trends as well).
I think a lot of this can be attributed the rise of internet-connected smartphones and mobile app development.
This led to a scenario where you had to have a separate backend API anyway to service the iOS or Android app frontends, so it was easy to justify doing an react- or angular-driven SPA for the web.
Plus the new mobile form factor demanded more front-end engineering work, so it made technical sense to have the frontend be completely separate from the backend.
This also explains the shift away from DOM-as-state, since you couldn't really drive mobile apps just from HTML, at least back then.
I guess we'll never know for certain whether we'd have thought SPAs were a good idea in the absence of having reusable APIs hanging around from mobile dev. It certainly made it easier for the browser to talk to the backend.
OTOH, we could just as easily have consumed the API from the app server and continued to render everything server-side. And, as you say, there are serious costs ("troubles") with going the SPA-route.
So, I believe we accepted the pain of SPAs because we thought it was a superior UX. But, I think it was a massive error and the costs have been far too high for the "gain".
There are much easier ways to boost the UX. Examples like typeahead that you mentioned can be just as easily simplified with a standalone JS-lib like typeahead.js. If you add in something like HTMX, it gets even easier to manage the dynamic bits.
Overall, I'd say we could've gotten +80% of the UX gain by sprinkling in dynamic interaction where most impactful, but continuing to render and manage state on the server. I've come to believe that React, Angular, Vue, etc solve a problem that should never have existed.
I think these are beginning to emerge. But, bonus points if these were abstracted in a way that it's the same framework (idioms, APIs, etc) and you could just choose your preferred language.
The backend doesn't render anything. It just sends html and CSS to the browser which does the rendering.
GraphQL has a few different advantages. Defining what data an endpoint returns on the client helps frontend teams build views without needing to A) define a new backend endpoint per view, B) cram everything for every view into one huge wasteful endpoint, or C) make a cascading set of render-blocking queries in each component such that a round-trip time of 250ms blocks the page for a whole second. It also requires defining a schema, but that's a side benefit.
This is hard to explain because the problems GraphQL fixes aren't actually problems on many teams. You need a complicated and deeply nested data model and UI, loads of different screens with similar information on them, and a backend workflow where API changes cause a lot of overhead.
It matters to your dev team.
A framework is a way of aligning how you approach writing things. It's a way of sharing responsibility between functional blocks of code. A framework is guardrails for how you think - it stops you just wandering off and doing whatever you want, and in a team that's vital.
When people switch from Angular to React, it’s not a framework-to-framework move. They may have outgrown a ready-made solution and want a fully custom one (could be some sort of home-grown framework, more aligned with their goals). React allows that, being a library.
Meanwhile, an actual framework-to-framework move can occur due to many factors like mismanagement of priorities or changes in HR situation (maybe they do not have success finding good Angular people cheaply, or they are already using Svelte somewhere and can reuse resources from another team).
yeah, no.
try for example to mix in a single page react components and jquery ui widgets
You need to understand what makes a framework a framework. onion2k’s comment does a decent job of explaining that, take a look. React has no guardrails and does not force any particular structure. That’s why there’s a plethora of frameworks built on top of it.
My litmus test to decide whether I'd personally classify something as a framework or library is to see what it's compared against and how people talk about it, as well as how they actually use it in a given scenario.
For example, people typically consider using either Angular, React or Vue for a project. Then, they talk about it very much like it is "an Angular project" or "a React project" because most of their code is limited to working within the confines of those (life cycles, state management, routing, patterns).
Does the fact that you could swap out one React statement management solution for another actually matter in that case for the distinction? It would... if anyone actually ever did that. Most people stick to whatever is the recommended option.
Same for the ability to run a whole Vue app under a specific div in a greater legacy site - in that case it would be treated more as a library... except that happens very rarely.
Then again, I don't really care about how strongly people care about these things, in my eyes one day the same codebase could be treated as a framework (a SPA in Vue with all of the mainstream packaged like router and Pinia, with hundreds of components and thousands of dev hours) and another as a lightweight library to be embedded into something else.
Would you like to elaborate on that?
In my experience, with something as great, size/ecosystem-wise as React, there will almost always be at least one mainstream package for whatever you might want to do with it, that integrates pretty well. Where a lot of things might come out of the box with a framework, with a library I often find myself just needing to install the "right" package, and from there it's pretty much the same.
For example, using https://angular.io/guide/i18n-overview or installing and using https://react.i18next.com/
Or something like https://angular.io/guide/form-validation out of the box, vs installing and using https://formik.org/
Or perhaps https://angular.io/guide/router vs https://reactrouter.com/en/main
Even adding something that's not there out of the box is pretty much the same, like https://primeng.org/ or https://primereact.org/
React will typically have more fragmentation and therefore also choice, but I don't see those two experiences as that different. Updates and version management/supply chain will inevitably be more of a mess with the library, admittedly.
Now, projects like Next https://nextjs.org/ exist and add what some might regard as the missing pieces and work well if you want something opinionated and with lots of features out of the box, but a lot of those features (like SSR) are actually pretty advanced and not always even necessary.
I know, people in our industry are lazy with words, but there are meanings behind them.
A framework is when you embed your code into the framework code, and the framework calls your code, like in React.
A library is when you call the library code.
React is a library not even specifically for Web. Angular, however, is a Web framework. It’s up to you if you want to compare the two, but you will not be comparing Web frameworks.
class HelloWorld extends React.Component {
render() {
return (
--- my code here start ---
<div>Hello World!</div>
--- my code here end ---
);
}
}
and React is calling my code with render(), I'm not calling React.React owns the control flow and the execution loop, which calls your code (hooks, render, ...) as needed.
With a library you own the control flow.
1. You define a function (or in your example a class) which calls React.createElement(...) one or more times and returns the result.
2. You set up the initial DOM as needed.
3. You call ReactDOM (another library, separate from React) and give it your function as callback.
4. ReactDOM sets up the main loop that handles updates to DOM when things change.
You can claim that ReactDOM’s reconciler “owns” the flow, but you have to keep in mind that reconciler is not part of React proper, that you are the one who calls it in the first place, and that React does not provide a reconciler of its own or impose any constraints whatsoever on the structure of your project or what you use to render things in the end or where (it could be not even DOM at all).
I imagine most people who think of vanilla React as a framework go with CRA or another template that brings in the boilerplate code, bundler configurations that make JSX magically work, etc., and acts as a sort-of-almost-framework (not a particularly good one, perhaps), which obscures the fact that React itself is merely a very generic library.
Ok!
If they're switching for user-facing reasons it's likely that they're using just the framework poorly. Changing your own code is usually a much more effective way to get a perf boost than changing an underlying library.
But the most startling thing that's changed since the late-90s is the 'tooling industry' and just how complex the tooling has become, for arguably marginal benefit to the users of the web.
> 1/0
Infinity
> 0/0
NaNWhile `1 / 0` is not a valid operation, it can be interpreted using limits. If `x` approaches 0, then `1 / x` will approach `Infinity`, hence JavaScript's result of this operation.
But with `0 / 0`, there is no unambiguous interpretation, so JavaScript defaults to `NaN` as its indicator for when a number is expected, but not received in valid form.
I'm not defending this behaviour of the language, just pointing out that there aren't "two different ways" of wrong behaviour at display here.
Maybe Go can claim to be simpler. But there are many runtimes that are popular and equally complex as nodejs.
I know, I’ll let myself out.
I like this quote, it reminds me to another favorite of mine, the Sagan standard: "Extraordinary claims require extraordinary evidence"
https://www.observationalhazard.com/2018/06/history-of-web-p...
You can see the impact we can make. A programmer's focus isn't just limited to following a straight line from start to finish and receiving their paycheck. Only poor soul like me are still out of job.
> People rarely pick “the best tool for the job”. They say that. But what they mean is “the tool I’m familiar with the most”.
Front-end developers are the most eager to pick up any new (or hyped up) technology. Going from webpack to vite, going from npm to yarn, going from node to deno. Plus, I work with React developers, and most would also experiment with svelte etc.
They absolutely love to learn and use new technology. At least that's my experience.
When you write a gui, you want to think in a tree of component. Ie React.
If you want to print, you think in document (html, …). That’s also a tree by the way.
Html does not have any composability. They try hard to inject that in it (web component, jquery plugin, …)
React (ie virtual dom) is a beauty in this regard and if you don’t use it, you would have a hard time creating any gui with a certain level of difficulty.
React makes development at scale of these things easier, and makes a website really a website (clicks are just triggering javascript instead of the classic post/get cycle that fetches new html). But it is completely unnecessary to build any level of GUI
Anyone who didn’t grow up building stuff prior to 2010 would have difficulty.
we don’t need react in 2024. And it’s only making things worse now. Not better.
html(
body(
div(
p("hello world"),
class: "blah"
)
)
)
where the tree was built using function calls. In such a system, HTML was often represented by an AST (or just a wrapper around a string!) and you could compose HTML together just by creating and calling a function.This is what JSX/TSX are doing under the hood: they're transpiled to a call to React.createElement. You don't actually need them, though.
I write the HTML. I upload the HTML. Works for me.
But that was a good article, it explains the rather odd and frankly underwhelming direction the web went in while I was out of it.
HotWire/LiveWire are then used for instant interactivity.
Is anyone else seeing people making that change?
There was no Javascript.
We ended up building (yet another) framework dedicated to rendering web components (https://rootjs.dev). It uses JSX for rendering HTML on the server-side, but no JS code is rendered to the browser at all by default. Web components usage is auto-detected and automatically injected into the page as a dependency, which makes for really good developer ergonomics.