
A tale of webpage speed, or throwing away React - todsacerdoti
https://solovyov.net/blog/2020/a-tale-of-webpage-speed-or-throwing-away-react/
======
kilburn
Most people here are criticizing the author for doing some dumb things. I
concur, but still think they have a good point.

First, keep in mind that the author's use case is a content-heavy app with
sprinkles of interactivity. This is _very_ important because it sets the
"webpage speed" goalpost to a concrete place: they want good lighthouse/first
load times and good SEO.

I've fallen into the same pit before. I've used Create React App with a custom
server-renderer, Gatsby and Next in different projects. None of the solutions
is truly satisfactory for the author's use case for a single very strong
reason: React's hydration process is both blocking and slow. I hope that
sooner rather than later React is able to offer a good solution for
incremental hydration, but it seems quite far for now.

Once you realize this, the only way to keep using React is to step out of the
mainstream and play with multiple render roots, parts of the page that never
get hydrated and so on. It is _possible_ to do things here, but it is
definitely a rocky path.

Of course, there are many wrong things the author explains that you can avoid,
but I'll throw a bone to them here too. Most "wrong things to do" they explain
are both wrong and understandable. And they openly accept it.

For instnace, one wrong thing to do that I've had to fight against a lot is
JS-based device-specific rendering. It is so much easier to implement a
"mobile ? <MobileScreen /> : <DesktopScreen />" than to make a single screen
that adapts properly using CSS that it's not even funny. Unfortunately, it
also breaks SSR, leads to janky page-loads and poor performance.

I fully agree that as of today and for content-heavy sites React pushes you
towards a pit of despair instead of a pit of success. You _can_ make it work,
but ... is it worth it?

~~~
aphextron
It's just apples and oranges. _Web pages_ should never even consider using
React. Maybe a bit of vanilla JS/jQuery here and there for whatever
interactivity you need, and then server side rendering for the content.
Building _web applications_ on the other hand, has been revolutionized by the
use of React. I would never seriously consider any other UI rendering library
right now because of the sheer volume of support and active development around
it and its' ecosystem. And hand rolling vanilla JS in a large scale web
application quickly becomes a maintainability nightmare. The alternative of
doing things old school with server side templates is _ok_ , but it massively
slows down your iteration speed through reliance on tight coupling between
backend and frontend.

~~~
tomc1985
> The alternative of doing things old school with server side templates is ok,
> but it massively slows down your iteration speed through reliance on tight
> coupling between backend and frontend.

Huh? Something like Rails lets you iterate on server-side stuff extremely
quickly. There is a _lot_ of functionality you can implement that doesn't need
JS at all

~~~
nawgz
Never developed in Rails - does it handle:

* composable templates

* reusable JS snippets

* hot reloading in your browser

And additionally, given that the topic is "building web applications", I can't
really understand how you think you can build interactivity without JS. Are
you proposing form-based updates or is your understanding of "application"
different than GP and mine?

~~~
tomc1985
> * hot reloading in your browser

We recently added this "feature" to our react-on-rails codebase, and the only
thing I can ask is... why?

Hot reloading on Unreal Engine is a hot mess with all sorts of little caveats
to think about. Meanwhile I can hit F5 and as long as my browser is configured
right I can guarantee there's no old cruft to deal with. Why in the world
would I want to add that kind of uncertainty in my work codebase??

~~~
nwienert
Whenever you’re doing design or interactivity focused tasks, and actually in
many cases debugging logic, hot reloading is not only a huge step function
improvement, but a categorically different thing.

The analogy I like to make is this: imagine a painter had to wait 3 seconds
for every stroke they made to show up. Would they be as good? Would they try
out as many variations? Discover new paths they could go because they had the
time to “test that weird idea real quick a few times”?

Hot reloading works especially well on React (and not I assume on game
engines) because React, with hooks, used algebraic effects, which means all
side effects are properly understood by the system and are undoable. So it’s
not as hacky at all as you’d imagine.

I never understood the hate for HMR as a concept. Perhaps your implementation
wasn’t great, but as a general concept it’s literally a game changer.

The same people who cast shade on it seem to always embrace incremental
compilation (like in Rust) for some reason, too.

~~~
tomc1985
I guess I can see it in that regard, and knowing the implementation of it is
complete and robust helps a lot. And I can see how this is useful for
interface design; most of the good IDE gui toolkits of the past preview live
as well.

But I also think this lessens the requirement for a solid mind's eye and
ability to visualize changes before you make them. Having come from desktop
development (with "live" gui development kits like VB) into webdev I guess I
got used to code-a-bunch-of-stuff-and-hit-reload pattern.

As long as it doesn't get in my way, I'm cool with it.

------
recursivedoubts
The initial motivation for intercooler.js (which the author forked) was
performance. I was working on a large bulk table update and building the table
dynamically in javascript. The performance was terrible (this was back in
2012, no idea what it would be like today).

I realized that I could just deliver and slam HTML into the DOM and that the
browser engine, written in C, was very fast at rendering it.

That turned into a pretty big javascript function, which then turned into
intercooler, which then turned into htmx:

[https://htmx.org](https://htmx.org)

~~~
nightski
I could definitely see something like intercooler boosting productivity. My
only concern (possibly unfounded) is that you end up designing all of your
server side endpoints specifically in an intercooler fashion. All of your
endpoints must now return an html snippet, which is specific to the design of
the page. So you have a lot of page specific endpoints. This is in contrast to
a REST api where the api can be designed largely independently of any one use
case.

If you ever need to switch away from intercooler you are going to have a large
undertaking not just on the front end, but now on the back end as well.

But I might be missing something.

~~~
mattmanser
If you don't need a rest API, all it does is make everything far more
complicated, i.e. every page now has two end-points, one for the html, one for
the data.

It's trivial in most web frameworks to have an endpoint respond in two ways,
one with all the html including head, menus, footers, etc. if you hit it with
a GET, the other just the snippet if you hit it with an Ajax request.

A REST API is basically a massive over-complication unless you actually need
it for a good reason, say you're running both a web app and a mobile app from
it.

I've used this technique occasionally for over a decade and personally have
always found this server-side approach very simple compared to juggling REST
APIs with client-side rendering when a client or an existing code base
demanded it.

I've also always found the defence 'you might need to switch' to be a flimsy
one. Usually when you do need to switch, everything is so different even your
'future-proof' API design needs a massive overhaul too because you made
assumptions you didn't even realize you were making.

Think of all those SOAP or XML APIs that were future proof...

~~~
nightski
Fair points. A couple of notes though - intercooler needs two endpoints as
well. One for the page, and another for any dynamic HTML.

I mean I switched from jQuery to knockoutjs to react all on one application
and the API served all those transitions well. So I'm speaking from personal
experience here. But that is anecdotal and maybe it's not typical.

~~~
recursivedoubts
One pattern that I have used with some success is to reuse end points and use
metadata that comes up with intercooler or htmx requests to determine the
structure of the output.

For example, if I have search functionality at

/search

and I'm implementing the active search pattern shown here:

[https://htmx.org/examples/active-search/](https://htmx.org/examples/active-
search/)

I'll re-use the /search url for the partial search results and check the HX-
Request header to determine if I want to render the entire search UI or just
the search results.

If you use hx-push-url as well, you can get a search dialog that acts like an
active search for the user, but also retains copy-and-paste-able URLs

------
tom_walters
This is the typical "we didn't spend any time thinking about our architecture
therefore we're going to blame our framework" article.

React is a great choice for certain use-cases, but when low-quality developers
are allowed to pick it up and apply it to everything you end up in a mess. The
same thing happens with literally any tool.

If you want speedy initial interaction times and manageable codebases, (and
requirement X) use the right tools for the job, and instil better, thoughtful,
development culture.

~~~
Udik
In general, these posts sound a bit like this: I tried jQuery, and after a
while it all became a mess; took up a Backbone project, and was good for a
while, but eventually it became too complex; then I worked on Angular and that
seemed a big improvement, but then... and finally with React my architectures
are clean.

While the reality is more like this: I had 6 months of programming experience
and used jQuery and made a disaster; with 1.5 years of experience I used
Backbone and I fared better; with 3 years of experience I tried Angular and I
was able to build a decent size application but ultimately shot myself in the
foot; and now that I have 6 years of experience my software quality has
improved a lot, it must be react!

~~~
tom_walters
Pretty much. It's similar to discovering the power of salt and pepper in
cooking. When you first use it everything tastes better. But the next step is
not to increase the amounts you use in every dish, it's to explore the much
wider world of cooking with herbs/spices/etc.

If your mindset is persistently "this framework/tool will solve _all_ our
problems" you're always going to have a bad time. Understanding the pros/cons
of each element is essential to becoming a good developer.

~~~
AtlasBarfed
It's almost like all "modern JS" are written by new programmers hired on the
cheap by companies to work on their new hip UI frontends.

IMO UI is generally something new programmers like because of the
visual/visceral "I built that", but once you get exposed to the sheer
annoyance of UIs, programmers will migrate to backend.

So the most experienced people don't want to be constantly undercut in price
by the incoming "talent", realize that WebUIs get chucked every 3-5 years
anyway due to browser tech churn, and move to data monopolization.

~~~
collyw
The JavaScript world changes so fast that no one is ever going to be very
experienced in the the they are using. I imagine that is partially to blame
for all the crap we see in the front end.

~~~
AtlasBarfed
I agree, the JS ecosystem is reflective of constant new programmers redoing
the UI every couple years, although I need to grit my teeth and admit that
React did at least standardize/structure the ecosystem for the last few years.

------
capableweb
> we’ve discovered that React also leads to some questionable practices. Like
> hovers in JS (rather than in CSS), drop-down menus in JS, not rendering
> hidden (under a hover) text (Google won’t be happy), weird complex logic
> (since it’s possible!), etc.

This is some strange reasoning that I have yet to seen myself. If you can do
the hovers states/drop down menus in CSS, why not do them in CSS, even if
you're using React? Seems to be blaming something on a library that the
library has no care about in the first place (which to be frank, seems
relatively common in web dev circles).

> In the worst case, we would serve you 2.5MB of minified (non-gzipped) JS

And holy guacamoly, how do you end up with this?! Seems that something was
surely wrong in the compilation options, forgetting to mangle names or
something, missing dead-tree elimination maybe?

~~~
Etheryte
Talking of bundle sizes, this isn't inherent to the React point being made
here but it's arguably too easy to blow up what you're serving. A common
example I like to reference is Moment[1] — unpacked size is 4MB, most of which
is different locales. If you _don't_ want to bundle all of those with your
project, you have to do extra work, instead of making locales opt-in. Perhaps
slightly less used, but a more prominent example, a widely-used table
component Ag-grid[2] is 25MB before being packed down. Instead of being served
as a modular set of components, it's mostly a big blob with minimal separation
of concerns.

The takeaway here is twofold: we need better tooling as well as better
practices for how to use those tools. It's both an educational problem as well
as a toolset issue. It is possible to build lean and fast pages, but it's
currently considerably harder than building gargantuan monsters. I don't see
the web bloat problem going away until the dynamic here is flipped — it should
be easy to ship small bundles even with minimal experience.

[1]
[https://www.npmjs.com/package/moment](https://www.npmjs.com/package/moment)

[2] [https://www.npmjs.com/package/ag-grid-
community](https://www.npmjs.com/package/ag-grid-community)

~~~
andrewingram
At my last job I always tried to be quite strict about adding additional
dependencies, if something was over 10kb it had to be very strongly justified.

Our designers wanted to add some SVG animations, they started off with Lottie
([https://bundlephobia.com/result?p=lottie-
web@5.7.2](https://bundlephobia.com/result?p=lottie-web@5.7.2)) because they
could export directly from After Effects, but I said no chance because of its
file size. Briefly considered Greensock
([https://bundlephobia.com/result?p=gsap@3.5.0](https://bundlephobia.com/result?p=gsap@3.5.0)),
but it was also too big for the kind of animations we were looking it.

I'll need to double check what we ended up with, but it didn't have any
library code, so each animation was just a self-contained bundle of SVG and
CSS animation code, and fairly small.

Edit: I asked around and SVGator
([https://www.svgator.com/](https://www.svgator.com/)) is what we ended up
using.

~~~
RandoHolmes
Too many people don't respect the risk of dependencies.

------
hliyan
When I first read the haiku at the bottom of the HTMX homepage, I had a flash
of insight.

 _javascript fatigue:

longing for a hypertext

already in hand_

What _are_ we doing? State management libraries? Hypermedia _is_ the engine of
application state. Send data to client as HTML and have the client apply
styles over it, rather than converting from JSON to local objects and storing
in some sort of reactive data store. You will find that semantically
structured HTML is almost as economical as JSON.

~~~
kungato
Why does is handling state on the backend better than handling it on the
frontend? You will always have the cost of waiting for the server to return
the full html every time you want something to happend and still you will have
cases where you are handling state on the frontend

~~~
hliyan
Theoretically, you have a point. Practically, you are reading this comment on
a website that not only does exactly this, but refreshes the entire page
(rather than a small block of HTML, intercooler-style). The performance
benefits are evident.

~~~
wwright
This site also has almost no state at all per-user.

~~~
7786655
Every time you collapse a thread, that's saved on the server. Then, if you
return to the page, it will render those threads collapsed. So that's a decent
amount of state.

~~~
wwright
I disagree. It’s Boolean and flat (there is neither sequential nor nested
logic around the state). It does recurse for each sub thread, but only in the
case where there is no state. There’s also no business logic built around it,
only display logic. It also is updated from exactly one location in the
application.

That said, it’s a very simple and effective design. It’s an excellent program.
But it’s not a fair comparison against other applications which, for one
reason or another, need significantly more advanced state.

------
onion2k
_We need to look at it from two sides: if it’s good for developers and if it’s
good for users. React was great at former and terrible at later._

React is not "bad for users". Developers build complex, fast apps with React
all the time. It _can_ be fast, but if you make mistakes with it then it's
easy to make something very, very slow.

The app I work on is huge. It's ~8MB of uncompressed React + Redux in
development (much smaller in production though), and pages include a lot of
assets so they can weigh in at 23MB in the worst cases. A complex page can
have up to 60,000 DOM nodes under React's control with thousands of event
listeners. It starts in about 3s and _never_ drops below 60fps.

~~~
lgl
> A complex page can have up to 60,000 DOM nodes under React's control with
> thousands of event listeners. It starts in about 3s and never drops below
> 60fps

Can one really make such affirmations regarding client rendered web apps? I'm
assuming these numbers aren't solely measured on localhost in some state of
the art development machine/device so won't it depend on the client's machine
specs, browser, usage, bandwidth, etc?

~~~
schwartzworld
I don't know what bandwidth has to do with react managing the DOM.

~~~
onion2k
A naively built app will do things like take some user input from a form, send
it off to an API and await the response, and then update the UI when if the
request is successful or display an error if there's a problem. That means the
user has to wait for the request to complete before moving on to their next
task. In other words, the DOM update waits for the network. If you have a slow
connection that feels horrible (snarky frontend dev note - if you build a
server-side rendered app it's how _everything_ in the app works. Sucks if you
have a slow connection.)

It's better for the user if the UI assumes the request has been successful and
updates the UI with a _temporary_ success state, and then undoes the update if
the request fails and gives the user the option to recover their update and
try again. Most of the time there won't be a problem (especially with good
client side validation) so they'll never see the recover state, and they'll
never need to wait for a network request to finish either. Obviously you
shouldn't use that sort of UX pattern for critical things though.

~~~
mattmanser
Ugh, this has got to be one of my biggest bugbears with SPAs. This pattern
fails far more than you obviously think it does, and when it does fail, it's
usually handled so poorly it's worse than the 'cure' you're peddling.

Give me a clean, server-side form submission any day over the "has it worked,
hasn't it?" inconsistency of SPAs.

------
swyx
> we’ve discovered that React also leads to some questionable practices. Like
> hovers in JS (rather than in CSS), drop-down menus in JS, not rendering
> hidden (under a hover) text (Google won’t be happy), weird complex logic
> (since it’s possible!), etc. You can have a React app without those
> problems, but apparently, you have to have better self-control than we had
> (nobody’s perfect!).

idk if this is fair. OP was using some pretty niche tools (clojure) whereas
best practice React metaframeworks like Nextjs may have addressed some of
those pagespeed issues.

additionally, I highly doubt that the author has replicated this functionality
by using his new turbolinky framework.

So the post is better titled "I improved webpage speed by throwing away React
AND a bunch of UI requirements". which is fair dinkum, but less exciting.

~~~
piranha
> additionally, I highly doubt that the author has replicated this
> functionality by using his new turbolinky framework.

Which functionality?

> a bunch of UI requirements

So your point is that you don't really know, but let's blame them for trying,
or what?

~~~
vezycash
It's hard but take a few minutes off before responding to snarky comments.

Please answer their indirect question: "Did you replicate every of the react
app's functionality in the app?"

~~~
piranha
This is why it took four months, we had to change all React-isms to something
that works in both modes. One particular thing could load less HTML, and it'll
require some attention to make it so - but as we're deprecating React version
of catalogue, it'll be easier to do.

------
mercer
As others have commented, this doesn't seem like it's React's fault.

But it does illustrate how React isn't a magical solution to the front-end
woes and how complicated the whole thing still is to do right.

I'd still use React for projects, but for now I've been incredibly happy with
the LiveView solution that Phoenix/Elixir offers (or the variants for other
frameworks. Blazor for C#, LightWire for Laravel/PHP?).

It's surprising how often I'll work on something and realize that the solution
is quite simple now, where before it would definitely mean some serious
thinking.

For example: libraries. I remember so many projects where I needed do do some
date formatting or manipulation. Moment.js was the obvious solution, but
including the whole library was not an option.

With LiveView I can just pull in whatever dependency I want, because it's all
server-side. It's only the markup diff for the specific component that gets
sent down the wire.

Or security. I need to show a user, but only a 'friend' can see the email
address (or other profile details). The 'old-fashioned' way would involve
separate API calls and a certain nervousness that perhaps I might end up in a
situation where the front-end behaves how I expect, but the API calls somehow
expose non-friend data.

With LiveView I can just add a conditional statement to the view, and since
the resulting HTML is all that does to the client, I'm done!

Of course this only works with a persistent and relatively low-latency
connection, but I can't remember the last time I worked on a project where
this wasn't an implicit assumption.

I'm perfectly happy using React/Next/Vue when necessary, but it's a really
strange experience to read these kinds of articles and threads these days when
for so much of my day to day these problems just went away.

~~~
piranha
LiveView is also very interesting. The main reason we went other way is that
amount of connections and state held on server will be really high, plus we
have some clients with bad connections and regular HTTP works much better on
those than websockets.

~~~
emerongi
LiveView can use HTTP longpolling.

------
madeofpalk
How on earth does React encourage the bad practice of “hovers in JS”? React
absolutely has zero influence on this - that one is entirely on the
developers.

I’m also exceptionally confused why the Pagespeed score was sitting at just
5/100 - it doesn’t sound like the dev team actually understood the result and
attempted to resolve it.

It sounds like the author has found some new technology they’re happy with for
now, but it sounds like all the previous problem were self inflicted and
they’re bound to repeat them again.

While different tech and frameworks has an influence in the problems you’ll
face, you’ve still got to do _good programming_.

~~~
schwartzworld
If you are writing JS styles, you don't have access to pseudoselectors like
:hover. A quick solution adopted by many is simulating hover with onMouseEnter
and onMouseLeave event handlers.

This can be remedied by using CSS or styled-components.

~~~
madeofpalk
This is nowhere near a common practice (I've never seen it on any work
project, or on community projects). React does not promote or advocate or make
it easier to do it this way, rather than the proper way in CSS.

~~~
schwartzworld
It is actually in the react documentation. [https://reactjs.org/docs/dom-
elements.html#style](https://reactjs.org/docs/dom-elements.html#style)

I'm not saying that's how it should be done. I'm just clarifying what the
author of the article was referring to.

~~~
madeofpalk
Correct, it is documented. That's what documentation is - to list out and
describe the API surface.

The entire documentation block for that is prefixed with a big yellow-box
warning:

> using the style attribute as the primary means of styling elements is
> generally not recommended.

And then it links to [https://reactjs.org/docs/faq-
styling.html](https://reactjs.org/docs/faq-styling.html) which just says over
and over again "use class names"

~~~
schwartzworld
So just to be clear A) it didn't always have that warning and B) I wasn't
defending the practice. Did you read the article?

------
_benj
Reading all of the cynicism on the comments I wonder if we are taking into
account the business context for the development of the app. I’m not a fan of
react even though I use it daily, but the licentious nature of react allows me
to build/modify features pretty quickly, albeit, low quality. I’m as idealist
as the next person about a good architecture, but if the code you are writing
is for a new product that is still trying to find a market-fit spending a lot
of time in the architecture of something that could drastically change doesn’t
make much sense to me.

All that I’m saying is that, as opposed to some other opinionated frameworks,
react let’s you do pretty much whatever you want, which is great for speed
development but can also exhausting in the huge amount of decisions that need
to be made.

~~~
nthj
If you’re going for speed of development, it’s hard to beat server side
rendering in Rails. The creator built Rails for speed of development and happy
engineers. It’s also very opinionated (convention over configuration) which
helps me just build out features rapidly without making thousands of pointless
decisions.

I am not opposed to React for like, a calendar application, or a particularly
complex part of a web app, but most web apps have 90% CRUD and 10% shiny.

And with well-tuned SQL and turbolinks dropped on, Rails pages load in 30-60ms
with no page refresh.

~~~
jack_riminton
The happy engineer concept is a much neglected one imo.

Rails devs who’ve mastered a lightweight js framework like Stimulus and
perhaps a webhook utility like ActionCable are immensely more productive than
a team of very separate front and back end devs.

Basecamp take this a level further whereby each dev is quite heavily involved
in the design process, and their designers can also code in Rails.

With Hey I think they’ve shown that it can not only be lightning fast but
pretty shiny!

~~~
nthj
Oh I agree, I lost a lot of nuance with my trite 1-sentence summary. Shiny is
mostly good judgement, good taste, careful organization and a lot of sweat
resulting in well-crafted CSS.

Especially in the past few years, as browsers have implemented a lot of
animations and scaling in CSS which offloads to the GPU. You don’t want
JavaScript/CPU doing that math anymore.

Component-based JavaScript frameworks “force” us to organize our CSS in the
same way outlawing cars in favor of bikes bikes ensures everyone follows the
speed limit.

------
lf-non
Not opposed to server rendering or backend heavy sites, but a lot of people
are able to get much better Lighthouse scores for fairly complex sites through
a combination of webpack code splitting, service-worker based caching, and
CDNs.

So, the problems here may have had more to do with the clojurescript stack
(which I am not much familiar with), or author's lack of familiarity with
javascript optimization strategies than react, SPA model or client side
rendering.

~~~
rjknight
Code-splitting is supported in ClojureScript. Compiled CLJS is just JS, so
service workers and CDNs should work in the same way.

However, CLJS really does feel like application development (which is why I
like it, tbh) and the community doesn't seem to pay much attention to the use-
case of regular web pages which just need some JS components to add
interactivity. Googling for strategies to optimise CLJS for that use-case
won't get you many results - you have to understand the stack well enough to
do it yourself.

------
llimos
For sites that are content-heavy I've started wondering if it makes sense to
have the content server-side rendered the old-fashioned way, and use multiple
React roots for the parts of the page that need to be interactive. You can
still use Redux etc. for managing app state globally (though not React
context), and you get most of the gains of load time, and of using React where
you need it.

It seems everyone uses <body><div id="app-root"></div></body> but React is
perfectly happy being scattered around the page.

It's just a thought, I haven't tried it myself yet - has anyone else?

~~~
catbuttes
We do exactly this within SharePoint. We have various react parts that look
things up in the database - sometimes quite heavy queries for reporting.

We have put together a small collection of fairly generic react apps that mean
we can put one on a page, put in some config and have it displaying a report
generated in SQL in about as long as it takes to write the SQL for the report.
We have used this approach for generic SQL reports, SharePoint lists, imgage
retrival and entry forms. Having the library of options to hand has meant we
can confidently assemble a new (fairly complex) page much quicker than
previously - and be confident that it will work as it is reusing known good
components.

------
dreamcompiler
I've been doing Ajax practically since Day 1, and in the olden days when I was
young and stupid I actually sent DIV IDs back to the server, which the server
would then reply with -- in XML -- to tell the client which DIV to replace.

Then I realized Javascript could do lexical closures which meant the _client_
could keep track of the targets, which also meant the server no longer had to
care about things servers shouldn't care about.

The next realization was that DIV IDs are global variables and thus in most
cases a bad idea, so now my event handlers automatically search upward (and
sometimes sibling-wise) from 'this' for DIVs matching classes or other
selectors, to keep the scope local.

This TwinSpark library seems like the next iteration of all the good ideas,
plus even more flexibility and proper separation of concerns, without JQuery
or other dependencies.

Bravo!

------
rawoke083600
Just use Svelte. It's a super simple API, the "trickiest" part is the
"reactive sections" but the whole API and reactivity part you can grok in an
afternoon.

In the past I have used Angular and React - these days I just always reach for
Svelte (speed and simplicity).

~~~
skc
I was happy learning Svelte, felt like a breath of fresh air with how simple
it was in comparison to the other more popular frameworks...but then when I
started to kick the tires of Sapper I quickly realized that that's where all
the complexity was shunted to

------
jevgeni
Surprised Solid hasn’t been mentioned.

This: [https://github.com/ryansolid/solid](https://github.com/ryansolid/solid)

~~~
theobeers
Ah, thanks! I was leafing through the Svelte tutorial recently, and I knew I’d
read about this other project, but I couldn’t remember the name.

~~~
jevgeni
I like it more than Svelte, personally. A little bit less magic (i.e. easier
to reason about) and more performance.

------
RedShift1
Looks like we've come full circle? First server side rendering, then client
side, now server side again?

~~~
sovietmudkipz
<jokes>Time to go bear on “client side” shares and bull on “server side”
shares. Quick, grab as much PHP as you can get!</jokes>

All joking aside, I would argue the client side vs server side is a false
dichotomy. The web has been doing a hybrid of both for a very long time now.
Each have their pros and cons and there hasn’t been anything stopping
engineers from using a mix of both, where it makes sense.

Now about those cargo cult marketers...

------
Demiurge
> It supports only modern browsers (not IE or Opera Mini) but drops that 88kb
> monster.

Whenever I read this, I usually take it the author is being serious. However,
how long does it actually take to load a 88kb library these days, is it really
'monstrous'? If this was the authors top performance drain based on profiling,
I commend their technical abilities.

~~~
piranha
Well, the reason why I started writing my own library is because I couldn't
get all functionality I needed from Intercooler. Why it does not depend on
jQuery? Because I wanted no dependencies. :-)

And a "monster" is sarcasm referring to that React bundle I described before.

------
ForHackernews
Is this approach similar to Rails Turbolinks?[0]

[0]
[https://github.com/turbolinks/turbolinks](https://github.com/turbolinks/turbolinks)

~~~
jack_riminton
I think it’s more similar to Stimulus or StimulusReflex? ie you can declare
the targets and actions of the JS within the html tags

------
mariopt
That 5/100 score is very very strange. Have you tried migrating your react
code base to NextJs?

~~~
ColeyG
Right? I think there was something architecturally wrong with the app that the
refactor fixed. It doesn't sound like react was the problem here. I sincerely
don't believe that this sort of change and therefore the decrying of react for
it makes much sense at all without seeing this guy's code.

------
Shorel
If anything should be learned from this article is this:

"We need to look at it from two sides: if it’s good for developers and if it’s
good for users."

It is a pity this change in thinking required the pressure from Google Pare
Rank, but now I see it as something very positive.

Always remember: code is written once, and executed thousands or even millions
of times.

No optimization is worse than "premature optimization", and you probably
misunderstand what "premature optimization" means anyway.

~~~
piranha
Honestly, I now think that the main reason was different. I was fed up by my
Macbook Pro's butterfly keyboard and started working on Macbook Air '15 again
at the end of 2019. And in three months I was increasing annoyed by our site
loading time.

And then it hit me. MBA is not the slowest laptop out there. It is much worse
for a large part of our users.

This is where I started thinking we should jump off the hype ship. :-)

------
davidtranjs
All of your issues like dropdown and hover in JS can be solved by CSS, why did
you choose to implement them in JS?

About complex logic, it is everywhere. I once worked at an big ecommerce
company and the server-side catalog page was more then 2000 lines, nobody want
to touch that page. But it would be easier with React since we can break it
down to smaller components.

Your 2.5MB minified bundle is actually too big.

~~~
tjpnz
>All of your issues like dropdown and hover in JS can be solved by CSS, why
did you choose to implement them in JS?

Because it's modern? In all seriousness I've often asked questions along these
lines and haven't always received great answers.

------
Brajeshwar
Here is an old story from 2016 but I hope this 3-part article is useful. We
used React during its early days, to help Aditya Birla with one of their
eCommerce websites.

1\. [https://alarisprime.blog/e-commerce-case-study-building-
fast...](https://alarisprime.blog/e-commerce-case-study-building-faster-
listing-pages-on-abof-com-part-1-cb99231a1e8a)

2\. [https://alarisprime.blog/e-commerce-case-study-building-
fast...](https://alarisprime.blog/e-commerce-case-study-building-faster-
listing-pages-on-abof-com-part-2-9aa0ac734c08)

3\. [https://alarisprime.blog/e-commerce-case-study-building-
fast...](https://alarisprime.blog/e-commerce-case-study-building-faster-
listing-pages-on-abof-com-part-3-4e4d32e0e884)

------
leon_sbt
Like what some people said 5/100 on the page speed score is pretty bad. My
site used to have this. It boiled down to two things that caused it.

1) I wasn't code splitting by page, and had a couple heavy dependencies (which
made things worse)

2) I wasn't pre-rendering my create-react app via react-snap. Meaning during
the CI build react-snap runs Puppeteer visits each page on the site, and
generates ready-to-go html versions of each page.

Those two changes took me from a 7/100 to a 95+/100 in short order. Makes
logical sense too. Now a days the site hovers at 85/100\. But I don't have the
time right now to reinvestigate it.

With the options at the time, I'm happy with my tech choices. If I had to
start with React again today. I would do Next.JS with a static build output.
Would save me a bunch of time scaffolding things.

------
jsguy
I think there are some interesting points here, though many (including the
author) seem to forget: React is a UI _library_ , not a _framework_. This
means it is up to the user to decide and implement everything else, such as:

* Code splitting * Loading of the code (at appropriate times, eg: ) * Any other optimisations

I think the author simply failed to do this well and then blamed the library
for their own shortcomings, and moved on to the 'next shiny thing'.

There are plenty of patterns you can use to make your React app responsive,
and many tools to help you achieve that, it's just a matter of being able to
implement those tools effectively.

------
ceedan
Thought this was a good read - and nice to see the progression of frustration
with front-end development throughout the last decade, and then the
introduction of mobile. This is a pretty common timeline for web devs who have
been doing this ~10+ years.

I wonder why the author did not contribute to intercooler rather than writing
his own version. Would it really have been that difficult to avoid inheritance
(or add an inheritance free api) and add batching to that library?

~~~
piranha
Batching is doable. I even understand how to do it in htmx. The problem is
that

1) htmx started later than I did

2) inheritance is like a plague, and I'd really want it to not exist

I'll try to explain my stance. When you're a developer, you naturally drift to
solutions which require you to write less or write faster. And inheritance
certainly helps with that in simple cases. TwinSpark had inheritance up until
we tried to implement sign-up/in logic.

Damned popups... Anyway, that's the day we've killed inheritance:
[https://github.com/kasta-ua/twinspark-
js/commit/5714ceea9836...](https://github.com/kasta-ua/twinspark-
js/commit/5714ceea98364efc41bc4c9c7b9031c2b23cf2a4)

And if you have two APIs - with and without inheritance - developers will use
the first one by default. And when it bites you it'll be painful.

So if Carson reads my rant and decides to remove inheritance - I'll gladly
move to htmx. If not - maintaining a library which is less than a thousand
lines of code is not that big of a burden. :)

~~~
ceedan
Nice thanks for the details - I didn't know you were in talks with them about
changes to intercooler, too.

Nothing better than a nice pop-up to ruin your day... they're a different kind
of plague

------
z3t4
The problem is how you think, and all frameworks is the same, they try to
visualize the tree structure. The key to understanding async is to think of
functions and state propagation.

------
withinboredom
Part of me wants to create a hugo template that takes advantage of this (or
htmx). You could make each "request" be a rendered snippet. :thinking: I may
try this out.

------
atum47
the whole React thing got so ridiculous that you almost cannot call yourself a
full stack developer if you don't use it on the front end.

------
seanwilson
Why not a static site (i.e. JAMstack)? If it works for this use case, it can
side step so many performance issues it feels like cheating.

------
elliottkember
Today I threw away all the sockets in my set that weren't 14mm, because I only
needed a 14mm socket.

------
andybak
> So I made a proof-of-concept implementation of our catalogue page in
> Intercooler and it worked! Except there was a dependency on jQuery and some
> other irritating stuff…

Actually the original author of Intercooler has a renamed 2.0 version that
removes some warts - including the jQuery dependency:
[https://htmx.org/](https://htmx.org/)

~~~
majewsky
HTMX is discussed further down in the same article.

------
kissgyorgy
This seems to me yet another story of "We didn't knew X enough, so we switched
to Y" or even worse, "we implemented our own".

No framework solves the problems of knowing your tools and learning every day,
React is no different, not a red pill for every problem, you have to know it's
quirks the same way just any other language/framework/tool you use.

------
maitredusoi
I love the simplicity of Alpinejs, why bothering with old tech like React ;)

------
terenceng2010
In the article though he does not mention whether React with SSR is an option?

~~~
piranha
It always had server side rendering. [https://solovyov.net/blog/2017/server-
side-rendering/](https://solovyov.net/blog/2017/server-side-rendering/)

------
blickentwapft
You can populate an ordinary web page with some react and get the best of both
worlds.

Plain javascript is painful.

It’s nit necessary to throw out react to address the issues identified here.

The author comes across as fairly junior.

~~~
andybak
> Plain javascript is painful.

Which is exactly why he isn't advocating plain javascript. You should take a
look at micro-frameworks like Intercooler (and htmx, unpoly alpinejs etc). For
devs who don't remember the days before megaframeworks it can be quite
illuminating to see a different way of looking at things.

------
ojosilva
In short, the OP changed the architecture from a client-side rendered app (in
React) to a server-side rendered one (built on a custom-made framework cloned
from Intercooler.js) and that resulted in a significant performance
improvement for their app.

Overall not a good critique of React as such to justify the "throwing away
React" title in the front page of HN. In fact, not a lot of good conclusions
can be drawn from the read. Maybe just "if YOU build/find YOUR own framework
for YOUR problem space excitement will follow."

On the other hand, I doubt the complexity issues, also mentioned by the OP
throughout the article, was solved by using the new framework. In fact:

> On the developer side, I think React is better still

So tit-for-tat.

~~~
adventured
6-12 months from now another article will be warranted, the author will have
changed their mind again. That's the pattern you see throughout the entire
thing, non-stop jumping. It's a solid bet as an indicator of the lack of
maturity as a developer, incessant tech hopping.

~~~
murkt
You mean in nine years its Backbone, then React, then server-side rendering?
Yeah, that’s tech hopping every 6 months in its finest.

