183 comments

[ 2.4 ms ] story [ 144 ms ] thread
All this to get a feature that was already prevalent 15 years ago in oldschool PHP applications.
I feel sometimes that we are running in circles in front end development. We had a good thing: Then we burned, step on it, and then recreated it because it was the best way to do things in the end of the day. :(
I feel like this is the inevitability of more and more tooling being released. Eventually there will be so much tooling that its hard to even work effectively as the signal to noise ratio plummets over time.
(comment deleted)
front end is such a shit show these days endless and then stuff runs for 1 month stable and instead of adresing real issues they come up with another rewrite.
You should really try something like NextJs, all the nightmarish parts of FE development are abstracted away. It makes me hopeful for a future where all the config files and tools are invisible and you just develop applications. All the TS, HMR, SSR, etc. is invisible to you and managing it is the responsibility of the people developing the frameworks.
You should feel that all the time.

But it’s not a circle, it’s an arc. If it were a circle, running as fast as you can in one direction would bring you back around to the former. Instead we hit the end of the swing and backpedal until we remember why we were going this direction in the first place.

Spoken like someone who doesn't need and/or understand SPA-style features. Look I get it, I've been developing with PHP for close to 2 decades but let's not pretend that PHP+jQuery (or whatever you are using for frontend interaction) is anywhere near as powerful as a SPA+SSR. And yes, not every site needs to be a SPA but there are some sites where that absolutely is the right call and pairing it with SSR can get you "the best of both worlds".
Who does need an SPA?
People who sell advertising for a living.
This is a joke, right?
No. From what I can tell the whole reason for a SPA is so that people don't leave your site. You throw away a lot of good things (like urls to content) so that you can push more ads at people.
Ah, I see your argument; SPAs are a preferred way to 'suck folks in' to a page and just have them stay there since they can't navigate in and out to the specific piece of content they want with URLs.

That about sums up everything wrong with our industry. Engagement over usefulness.

yes but none of that has anything to do with SPA as a technology.

the point of an SPA is so that i can share code and data for different pages in the browser without having to get it from the server for each new page.

it does not at all prevent me from using links to the outside or even within the site. (i just built an SPA where all navigation is done via regular links, each view has a different url, they all can be bookmarked, and history works too so you can go back and forth using the standard browser buttons, and links to certain resources take you out of the app)

> the point of an SPA is so that i can share code and data for different pages in the browser without having to get it from the server for each new page.

You still have to get it from the server for each new page, you just do it in the background.

i don't need to get the code. nor the markup. that's already loaded in the browser. if i need to get anything, it's raw data. i also don't need to send anything back so i can manage state. being able to load data in the background can also improve the user experience. and for those apps that don't need a backend, i won't need to get anything ever after the first load. SPAs can, if written right, function completely offline, once loaded.
> also improve the user experience

It doesn't. Most users don't actually notice.

Well, not long ago I made an in-browser WYSIWYG mouse-based diagram designer. I redefined a huge share of the default browser behavior.

It was also the first SPA I made, in a career of decades. I also think I do not regularly use anything that benefits from being an SPA (I don't regularly use that diagram designer either).

People/stakeholders who want use the browser as an application platform.

Think data analysis tools, Intranet tools, e-commerce, and a host of B2B stuff?

I know, it all starts with a filterable list or a shopping basket, where page reloads or ajax "sprinkles" (regardless of what they're loading, HTML or JSON) are absolutely OK.

Especially the fully old-school approach with the page reloads - it can work and scale for simple and predictable requirements.

Until it doesn't - the first page with 5 interdependent autocomplete inputs takes weeks to develop and fix, the modals can't have routes without piles of jQuery hacks, and so on and ao forth

E-commerce is an example that clearly does not need SPA features. It needs great performance and SEO, not flying bells and whistles.

If a five input form takes week to fix, you have engineering problems beyond any choice of framework…

everything i built in the past few years only needed a generic CRUD backend, if it needed a backend at all. there is no application specific code in the backend, and the latest app i am working on is completely static as far as the backend is concerned. it could even be served locally via file://

all the application and interface logic is in the browser. this is only possible thanks to SPA.

Do you persist any data? Where does business logic reside? How do you validate inputs?
with a backend, data persistence is simply CRUD. for the backendless app, it's all in localstorage, and it can be downloaded into a file as backup. all the logic is in the browser, just like any desktop application. you should not need a server to manage personal data that is stored on your computer.

of course it is a tradeoff. if the user wanted to save their data outside the browser every few minutes then that would not be practical or if there is to much new data being generated so it doesn't fit into localstorage. i'd either need a server (even if running locally) that can save that data without user intervention or i should not use the browser as a development platform. in such cases a browser based SPA would have been the wrong choice. maybe electron, or a traditional desktop framework

Excuse me while I go to my screaming room to imagine Google Maps as an MPA.
You don’t remember MapQuest?
I do, and that's why I moved to Google Maps as soon as it came out. The performance and UX of MapQuest was terrible.
That sounds pretty cool actually.
My company does. It is a desktop level app written for the browser. And it is mostly done in Vanilla JS. No SSR since time to first load is irrelevant. They are about to sit down for an hour of solid work on a trusted platform, not buy a pair of shoes from an unknown site where waiting 500ms might make them change their mind.
Main side project of mine is a Strava-like web app to upload bike rides. It’s intended for personal use, so I don’t care how long it takes to load for random visitors arriving for the first time. I don’t care if search engines can properly load the page for content previews. I don’t care if someone’s ten year old Android device chugs on the JavaScript. I don’t care about dealing with the headache of making whatever JS library I’m using work with hydration.
This is a weird comparison. You can use PHP to power an SPA with SSR. It's not an either or.
I never said it either/or, in fact I’m using PHP to power an SPA right now. I was saying that pretending that PHP alone was sufficient (for both customers or dev speed) was silly.
My own website is a kind of hybrid SSR/SPA in PHP. Navigating pages with JS enabled (JS is entirely optional) seamlessly updates the relevant DOM nodes with an AJAX call (and uses the history API etc), but going to a page fresh is entirely PHP.

It was fun to write. Relevant code is here:

https://github.com/ldyeax/jimm.horse/blob/master/j/j.php

https://github.com/ldyeax/jimm.horse/blob/cb6a1c03504cbe6b63...

I actually uncovered a niche bug across multiple browsers with this PHP code. In at least Firefox and Edge, if a page is cached with a fetch using accept:text/json, the response will be shown from view-source of the html page you have open, even if the content is different when you fetch the page with accept:text/html

SSR usually means doing the front end JS browser render on the server, not just the more generic task of producing an initial HTML from a server.

The idea is the same code can work on front end and backend. On NextJS it will run your React on the backend but useEffects will not be called. Just the initial render is saved and piped to the browser.

If you're building an SPA for an Ecommerce site you've seriously misunderstood the web.

These days you can slap together a very capable PHP based Ecom solution using Livewire for those sections that need interactivity.

People really need to realise just how detremental to the user experience it is to have mountains of JS being needed just for an ecommerce site.

15 years ago a frontend build was not a thing. You managed what few javascript and CSS dependencies you had via the order of the script and style tags in the header. Now a frontend build is a baked in requirement of any user-facing application, so whatever you end up doing in whatever language, you already have that one build to manage. If you choose to build your application in anything other than JS/TS, you are effectively adding an additional build to the project, with all of the associate overhead. If you stick with one language and one build, you are eliminating large swaths of unnecessary complexity right off the bat. Not to mention that you don't have to hire for the additional language for the dev team.

Unless there is a legacy system driving the requirements in a different direction, my default application architecture is always going to be server-side React at this point.

> Not to mention that you don't have to hire for the additional language for the dev team.

Or maybe hire people who can code in more than one framework.

You could, but I doubt anyone with budget responsibilities is going to appreciate you making hiring more difficult and expensive.
I hope you realize how depressing this statement is. “Coding in more than one framework” is an extremely low bar to hire for.
User facing in what way? There seem to still be a ton of new RoR or Django projects without react/ or angular out there.
Using facing meaning they have a UI. Even the simplest of which has some degree of CSS and generally a bit of JS. Unless you want to go back to the jquery and vanilla CSS days, which I can promise you none of the your developers will thank you for, you need a frontend build of some kind.
I want to go back to the Jquery days. It’s more than sufficient for 95% of websites.
As a mid-seniority developer, I'm just now starting to grasp the harsh reality of a full refactor. We always think we can improve the speed and code of a website but, man, that's really though.

I always remember the "let's throw away Windows ME codebase for NT" scenario. Sometimes giving up is better I suppose.

>"let's throw away Windows ME codebase for NT"

Well the Windows 9x codebase was always mean to be , eventually, thrown away. It existed only to be able to run the OS on very low hardware (eg Win95 run even on 4 MB of RAM).

Certain websites are so overbuilt though that theres plenty of low hanging fruit. I’d say a very healthy majority of the websites I visit could replace whatever bulky mess they have with static html and still serve me their content and ads. Then the website would probably be orders of magnitude more performant refactored in html.
This is why we have the strangler pattern, it's not just for backend apps. Start small, tackle the biggest risks first, deliver incremental value.
I have been part of 2-3 strangler refactors... I don't think we ever reached the turn off the old app part.
Did you end up with a net improvement, though?
Me too, but I don't see that as a failure. Sometimes it's a case of 80/20, and refactoring that 20% might just never be worth the effort.
One of our teams rewrote their legacy cloud product in an interesting way. Instead of gradually replacing components of the existing product, they forked it, rewrote most stuff from scratch in a different branch using a different stack (different UI/UX also) and called it version 2.0. The old version was still maintained (bugfixes, tech support etc.) but they stopped selling it. Instead, they started selling version 2.0 (new clients were unaware of the difference). Version 2.0 did not have full feature parity with version 1.0 at the start because it would take years to reimplement everything. What they did was gradually migrate clients from 1.0 and 2.0. Most clients did not need all the features so they were OK with version 2.0. Those clients who refused, stayed on version 1.0 for a few years. Then the team was slowly adding more and more features to 2.0 for the next few years, and more and more clients were willing to migrate, and this year the last client migrated to version 2.0. It took 4 years overall. The new version was designed to be more stable, more scalable and more maintainable, so it's a net win in the end. Also, since it was basically a new product, they were able to experiment with new ideas without the constraints of the old product.
There's usually a subset of any given codebase that gets changed substantially on a regular basis, and the rest mostly stays mostly the same. If you can get the parts in the former category replaced with something better to work with, that often gives you most of the advantages and you can migrate any remaining bits as and when you can be bothered.
>We always think we can improve the speed and code of a website

You're not wrong, but the moment you speed up your site to being usable then the stakeholders above you are going to add 50 more (conflicting?) requirements until the site is slow as the old one.

168 mb of bundled js? they must've written a fully functioning unix-like kernel too, yeah? or embedded Taylor Swift's 7th album. otherwise, I don't know how the number is as high as that.
I wonder how many of the top npm downloaded modules you could fit into an amalgam vendor minified build before you hit 168 MB.
(comment deleted)
All malware infested varieties of is-true for certain!
Surprising that at the point when it crossed 100mb there was no-one on the team who raised any concerns. Perhaps this was a case of boiling the frog?
What I understood from the post was that it was only 168mb because tree-shaking didn't work on whatever version had support for server-side rendering. With working tree-shaking the bundle these developers were working with during development would be considerably smaller.
Wouldn’t be at all surprised if no one was paying attention. Chrome on a top spec MacBook can chew through 100MB of JS without thinking about it. Someone on an old machine is screwed but hey, “works on my machine”…
Probably bundling the server side dependencies into the client. I’ve also seen this happen when people add uncompressed 4k png images and the build tool is configured to inline all static assets. Obviously there was a lack of domain knowledge in the company or this wouldn’t have happened.
(comment deleted)
This stinks of no-one-knows-what-the-fuck-they-are-doing-itis, a common problem in the software engineering community. When mixed with a deadly dose of sunk-cost-fallacy-itis and project-death-march-itis, the only way out is adding more JavaScript until it creates a singularity from the accumulated mas and sucks the project into oblivion.

Trying to fight one of these off now. We don't need a fancy shit ass UI. We just need stuff that works and is simple. But plenty of one-trick pony developers and architects who build complicated mechanisms out of piles of nodejs and microservices which merely consume time, energy and attention and delivery sweet fuck all ROI.

> no-one-knows-what-the-fuck-they-are-doing-itis

This is so funny. I feel like in the old days it would be called out without remorse, like an old hand putting down a maimed horse. Nowadays you have to tapdance around the issue to such a degree that you look insane to try, people will just spout jargon longer than a ducks dick and your manager will sucker down.

I've long given up on tact and politics. You say what it is. If someone doesn't like that, move the fuck on.
be sure to mock people with +20 years software design and development experience, too...
Some of the people I am mocking do have that.

Also I mock myself regularly :)

I think it smells of the common trend in javascript to grab any old package and use it if it scratches an itch. look at lpad(and that debacle). back when i was doing compiled stuff (well even now in scripted land) you'd look hard at whether or not you needed that dependency since every dependency is a liability. and of course you'd manage the dependencies by hand.

kidsthesedaysgetoffmylawn

That's most modern software development though. Drag any old shit off the internet, dependencies, malware and incompetence included, then execute it as some arbitrary user with full access to your mission critical data and an outbound network connection. Maybe if you're big enough to have a security or compliance guy they will at most want you to buy in something that does a half assed attempt at tracking dependencies after it's too late or intercepts traffic pointlessly on the way out crippling your business inconveniently sometimes.

I tend to just use whatever Debian ships with package-wise when I'm doing something for my own purposes. People laugh at me. Their funeral.

Heh, it's fun doing SCA and SBOM these days and having the report generation break because the servers run out of ram building the list of everything the devs included. Then the dev team comes back and says it's impossible to run the application out of ram, they'd have to include thousands of modules and there is no way in hell you could keep that application working over time and manage to audit it. Then you show the devs the trace logs for the error and they shudder in terror.
What are you using to generate SBOM these days?
This is due to a long time of the standard library being seriously lacking. Even today, group / groupToMap still aren't standardized, nor are iterator methods. It used to be even worse though.
Very true. This is one thing I like about Go. The standard library is very complete. I can do most things I need to do without having to pull in any external dependencies.
Good luck with that. I'm one of a handful of people on a team that maintains a native iOS app and the powers that be want to transition it to be a minimalistic container for a React web app so they can "just design it once and push changes without needing a separate App Store submission". I can fight that only so long, and then we need to let them do it and prove to themselves and every user that the UX will suck. The best they can hope for is mediocrity.
I imagine it is not pure js code but a lot of embedded svgs and inlined assets and styles.
a fully functioning unix-like kernel is more like 0.03 megabytes

remember the pdp-11 was a 16-bit machine, and there's also c64 lunix, etc.

I gotta think it was more than just JS? Some non JS assets and etc maybe?
If it's not like... large language bundles or images or whatnot, I suspect it might be a lack of technical oversight and everyone just adding their favorite library.
Apparently you’ve never had to shed file size from a multiple megabyte react bundle shat out by webpacker
Shall we make a bet that it was node.js based?

That has the ability to spiral out of control completely if you don't keep a really sharp eye on what includes what.

It was Angular. It may have been served by Node, but Node wouldn't have been included in the bundle (unless something had gone terribly wrong, which...I guess is possible, given the article?)
(comment deleted)
Author here. At the time, Angular relied a lot on the AOT compiler and tree shaking to keep bundle sizes down. No idea if this is still the case.

If we built the app with the stable branch the bundle size was orders of magnitude smaller: less than 200kb. Still a bit of a chonker, but more reasonable than the ridiculousness the experimental SSR branch spat out.

I’m really curious what this article would look like if it was written from the perspective of one of the “boots on the ground” developers that spent 8 months on the original PoC, rewrote it in the 7 weeks, and is still maintaining it today.
They mob programmed and this lead seems hands on. Id guess pretty similar
168mb holy crap!

I'm glad he got to the real issue at the end. Doing a full big bang rewrite with no deliverables for 8 months. A classic waterfall project.

Maybe the react rewrite was the right call at that moment in time, but there were a serious of huge mistakes that led them there.

> Doing a full big bang rewrite with no deliverables for 8 months. A classic waterfall project.

I've seen the same thing for agile projects too.

I can't really see how that could be classified as agile. Using an "agile" methodology maybe
to be fair, it's e-commerce. an MVP of a _working_ e-commerce site still needs a shitton of functionality (cart management, product management, sku management, backend data, tax calculations, etc etc). i'm not surprised at all that it took this long. he didn't mention using any frameworks, so i'm guessing they made some bespoke thing.
I gotta say, I sympathize with their "goes against every instinct" plight. If I had joined a team 2 months ago, and they'd been working on something for a year, and I was thinking "we should scrap this and start it over from scratch," I'd be really, really suspicious of my own thinking. Scrap and start over is such a tantalizing programmer thought for something that seems complicated and broken, and you'll almost always want to do it, and it's almost always the wrong call. Glad it was the right call here.
Was it though? I mean, the goal was SSR, but if they had a fully functioning site sans SSR, why not ship now, then deploy SSR whenever it gets baked into Angular?

They were using Angular's dependency block them when I don't think they really needed to be blocked to ship a product.

it was the right call.

> The relaunch of our ecommerce website had one goal: deliver blazing fast performance with Server-Side Rendering.

you’re suggesting they ship a rewrite that doesn’t do the one thing they’re rewriting for? at the time they also didn’t know when ssr support would be available.

they switched and shipped ssr support faster than it would have been available otherwise.

You see both sides of the coin often-- people are often too quick to go for a rewrite. But then you also often see the "rewrites are almost never a good idea" camp that dismisses the benefits too quickly.

The reality is rewrites are often appropriate but they need to: 1. Have a clear tangible benefit (or ideally many benefits) 2. Be as tightly scoped as possible to achieve the above benefits. Rewriting everything at once is a horrible idea in all but the most egregious cases. 3. Be as incrementalized as possible.

Expanding on your first criteria. The technology stack is fundamentally wrong is a good reason for a re-write. Language too slow. Doesn't handle the workload well. Other stacks have a better ecosystem.

Re-writes are also needed when the architecture doesn't match the problem space well. This can be incrementally done. Single threaded loops instead of using parallel-safe constructs like tasks and jobs.

Expanding on your point, rewrites can work if they can be accomplished in finite time.

It's one thing to rewrite a website, where the project timeline is measured in weeks.

It's another to rewrite large project where the -estimate- time is years.

We have mature desktop systems that have been in continuous development for 25 years. That might blow your mind, but its the same timescale as say Excel of Word. The question of rewriting, regardless of the tech stack, is moot. It would take years of effort (optimists think 5, more likely 10) and would cost a fortune. With negligible benefits beyond "now written in a language with a bigger developer pool".

I'm the first to admit that there are disadvantages to the stack. On the other hand we are where we are (doing well) thanks to that stack, so it's not all bad. We're still using code laid down in 1996, while being a modern desktop app. We're still the leaders in our field.

The time (aka cost) to rewrite is the major hindrance, and far outweighs any issues using an uncommon stack.

The best systems I've created came from iteratively experimenting with the language / API / whatever. Build something for the sake of learning, throw it away, build another experiment to learn, throw it away, take a shot at the real thing, throw it away, etc. It starts to feel like if you rewrite and think about the problem enough you'll eventually reach a point where you can write or rewrite the whole system in a week. Which leads me to conclude:

Systems that can be rewritten should not be rewritten. Systems that cannot be rewritten should be rewritten.

It's not quite true (not in all circumstances), but it's close. I think most enterprise / pile-of-business-rules software falls into the latter category, those systems cannot be rewritten, but they should be.

All of my best work has been done this way. Most jobs won’t allow it, but really good software managers will
Spot on. Inexperienced people want to rewrite because they may not know the problem domain. Experienced people do rewrite because they know what they want to achieve.

And there's many ways to rewrite and migration strategy other than full rewrite.

A rewrite makes sense for two reasons. 1: No two people on your team understand the code from start to finish, or 2: (as in this case) the current stack cannot perform to the standards required, and another stack can.

Too many people just want to remix code or rehome it, taking the papers out of the old book and putting them into a new cover. At the very least, take the time to make sure you fully understand the system before you replace it.

Actually read the source code before a rewrite.

That the project was supposed to ship in three months is an important part of the author's specific experience.

That they gave the project another two months is another important part of the experience.

So the specific project was clearly a failure. They weren't talking about rewriting working code, let alone code that was making money.

To me, it looks like it took a lot to violate the never-start-over-prime-directive-for-progress in creative work.

The difference here is this person risked their job directly to do this.

You need help if a lot of money to be able to make wagers like this. And I see no reason to risk my personal livelihood over bad corporate decisions.

I guess that's the difference between what I do and the crazy startup world.

I know most managers wouldn’t agree but I think having fuck you money is good for the employer as well as the employee.
> *"We delivered the new version of the site after 7 weeks"

I know everyone is focusing on 168MB, but ...

The bigger issue that needs to be addressed for this leader is - why did the previous project take 10-months, when that same team was able to deliver an entirely new rewrite version in just 7-weeks (without all the code bloat as well).

a large part of why it took 7 weeks was the work they had done over the last 10 months to gather requirements and translate them to code. the exact form of the code is merely the last stage in the process - i wager it would have taken them considerably longer than 7 weeks if they were starting the react site from scratch.
you are certainly correct. But there is a sentence that stood out to me, one where he said that devs needed to wait up to a minute to see their changes. I’ve personally felt the slog of writing code that takes easily 2 minutes to see changes, compile, flash unit, connect via bluetooth see if change shows what’s expected in some blackbox app. It’s maddening, and slows things way down, trying to keep the thought of what you were trying to do for that long is difficult and leads to lots of wasted tests. I largely suspect it’s an exponential function and the longer the feedback the exponentially longer the code takes to write.

1 minute is a long time, and I could see if you could get that loop under 10 seconds you could shave off months of dev time. Hell, I just recently changed a test timeout I was working with from 2 seconds to 1 second, and my morale improved in ways that surprised me even knowing all this.

In fairness, rewrites can be quite a bit faster than an earlier incarnation. By that point you've identified key gotchas, can simplify quite a few things, etc.
Its not surprising honestly. There's a point in a codebase's life where it grows to this size that's hard to put all the moving parts into your head. Bloated, corrupted, every change takes careful caution to make sure it doesn't affect some other part downstream. You might know certain parts are not optimal or efficient, but you don't have the time to stop iterating on other tasks and fix these inefficiencies, let alone revise all the other built on parts that depend on this sub optimal component.

A clean slate on the other hand is a lot easier. There's no vestigial pieces. No dependencies on hastily written functions you never got the time to rewrite the right way. You aren't locked into some version of a library from three years ago, you can use all the latest tooling.The shorter the codebase is in total, the easier it is to grasp the scope of how it all works together and move faster, knowing where other things should fit in a much simpler mental model.

It seems like a significant portion of that 10 months was spent refreshing the angular 2 repo hoping to see a change.
They literally picked the wrong tool for the job. The the tool they picked did not have the feature they needed.

That is an utterly moronic decision.

Why does -he- need to address the poor decisions of the person who was in charge before he joined?
So there was a measurable problem (large bundle size) that they sought out to fix (in addition to upfront loading time). The first thing to do would have been to _not_ engage in SSR, or Angular 2, or any other big architectural change without first checking if actually properly slimming the bundle would have helped first. Next, how do you proceed till almost ship without actually solving one of the core initial problems you set out to fix? Before porting the universe, it seems like you should at least remove that risk or convince yourself you know how to do it. I'm going to go on a limb and also completely disagree with the conclusion that a React rewrite was the right thing to do. My experience is that engineer morale isn't maintained by staying in framework and rework hell - instead, morale increases when engineers have opportunities to deliver high-value experiences to users. Not shipping is a common and understandable reason for engineers to leave, and if your employees are hankering to leave because the tech they use isn't the current flavor-of-the-month, you may need to reassess your cultural values screened during the hiring process.
I've seen projects devolve like this when everyone is tasked with a part of app logic (the checkout page, the cart, etc..) but no-one is responsible or accountable for the sum of the parts.

Oh you want to rework on the routing or tooling or anything like that impacts other parts of the app? Good luck getting 5 teams to sit down and agree.

While the 168mb is ridiculous, I'm more facinated by the choice to depend on an unimplemented feature from a group/company they had no control over or contracts with. I would hesitate to depend on things which haven't been released for a few months/years. I realize the web moves fast and some might prefer working with new technology, but this sounds so weird to me.
Other commenters here are focusing on the bundle size or the choice of framework, but I'm really surprised by the stack: It's an ecommerce app, why do you need a SPA for it? I really think people have just forgotten how quick and easy it was to write SSR code that has a bit of interactivity on the frontend as-needed, and has gone full in on SPA all the things.

I wonder how long it would have taken them to write with plain HTML served by simple views.

I gotta admit, I was reading through this article thinking "and so you rewrote it in boring old HTML, right. Right...?"
Yeah, I did get a bit dismayed at "so we rewrote it and kept all the complexity, but used a framework that had the critical feature the old one didn't".
Sometimes I think the best thing an eCommerce Company could do is move their home-rolled eCommerce app to Shopify / BigCommerce / some other eCommerce SaaS. I imagine that 8 months of getting to know a true eCommerce platform and purpose-building plugins would result in a pretty reliable eCommerce app. Especially if you never have to worry about if your Cart, Check-Out page, or PayPal/Google Pay/Apple Pay plugin is going to break on every update.
> The company's first website was an AngularJS single-page application. AngularJS didn't support server-side rendering, so the website was slow to render on first load, but snappy once everything had downloaded.

That sounds like a pretty decent concession. I wonder if it was ever even a real problem. I'll bet the real problem is that nobody was willing to call it done.

He mentions that this is not a good UX in ecommerce space.

I think I agree.

If I have a choice between buying stuff on Amazon.com and Walmart.com -- and if one of the two gives me sluggish UX everytime I start my user journey. The other competitor site would eventually become my default go to and get all my money (everything lese being equal).

Brands are built at touchpoints -- according to my marketing prof -- and I believe it rings true.

This is assumin that you are losing nothing for indefinitely working on it, which is probably not true
I tossed about 18 months' worth of work on the frontend for our upcoming app, and started over.

It's been about eight months since, and the new app is really good. It will be a hundred times better than what we had.

Since we didn't do the MVP thing (which pretty much forces a "sunk cost"), we could do this.

At my previous job, my assignment was to rebuild a front-end 10 years in the making; the company had lost (idk if they fired him or he moved on, I suspect the latter as he was one of the founders) their previous developer, who was both not a very good developer and very productive.

But yeah, when I joined that software had been built for over 8 years, using technology and practices from the 2000s (think AJAX where X is XML, a PHP back-end that concatenaded XML tags, and a Dojo front-end), and my goal was to rebuild it.

I spent 2.5 years there, using Go as back-end so it's all integrated (one issue was that the PHP runtime they had at customers couldn't be updated because RHEL didn't have a newer version in the repos), React as front-end, etc etc. But there was just too much functionality to rebuild, and they didn't / couldn't find other people to hire (until I quit, because of course).

In hindsight, while PHP wasn't really my thing, I should've focused on improving the existing codebase and then only incrementally improve and replace things in-place. I mean at the same time, I knew a full rebuild of that was a Bad Idea, but that's what they wanted and I wanted to do stuff in Go as well so I didn't challenge it too hard.

But yeah, I could've easily made the back-end twice as fast with at worst a week or two of work; half the back-end's processing time and memory usage was because they took that concatenated XML, parsed it, and converted it into JSON. Because at some point the previous author realized JSON is the new cool kid on the block.

Well, I wrote both the backend (PHP), and the frontend (Swift).

The backend is too complicated, because I originally wrote it as a general-purpose server, and it is now specific, but it works fine. No need to rewrite, although I’d love to.

The frontend had been “accreting” features, because it was really a high-quality prototype.

When we had nailed down the functionality, I knew this was a ball of mud that I didn’t want to maintain, so I factored the business logic into a standalone library, and most of the work has been on the “chrome” for the app. It’s not-simple, but much more straightforward than the previous version.

Also, this time, we brought in a professional designer, and have been applying style from the beginning.

I don’t have much experience with frontend frameworks / libraries, but I really dislike the way this article presents React as the silver bullet.

Maybe it is factually accurate that Angular was the wrong choice for e-commerce (at the time?). I don’t know. Without SSR, was there really nothing feasible they could do to reduce the page load time? Did Angular make tradeoffs that are better for a large, interactive web application; and you want a different set of tradeoffs for ecomm use cases? Or were they just stuck with the wrong tech at the wrong time: complicated enough that it’s too slow in Angular, and the project hadn’t caught up to them yet?

That JS bundle was doing _something_ (probably lots of somethings). How many features did the React rewrite drop? Could you have removed those features from the old codebase, or would that have been politically infeasible at the company? (“no, don’t delete that” vs “yeah, we can live without that, you don’t need to implement it” -> author gets to add a Loss Aversion sidebar). Are there still items in the backlog to re-implement missing features (that the team intends to complete)?

Development effort compared between stop-the-world rewrites (in order to hit their 7 week “really big shopping event”) vs rewrite following ongoing feature development and the painful merges mentioned in the article. Obviously business appetite changed for a stop-the-world rewrite, but could that have been identified earlier?

Changing requirements: did the Angular upgrade start with “we need SSR” as a top requirement? It seems more likely that there were a bunch of benefits / requirements for a technology upgrade, and over the previous 10 months they’d discovered SSR as a blocker. Erasing the other improvements makes the 10 months vs 7 weeks sound very impressive, but seems disingenuous.

Maybe my expectations are off for a blog post format.

> I really dislike the way this article presents React as the silver bullet.

It didn't read like that to me, I thought the point was they went for a rewrite on the new breaking changes major version, expecting specific features to eventually land, were waiting for them, and React had them already.

So it's more (to me) like 1) don't do that; 2) if you're going to do that maybe take a step back and there's something else out there already or that's a better fit.

Author here. That’s the takeaway I was going for.

It could have been any technology. The silver bullet is choosing the right tool for the job.

I don’t have an attachment to any particular tech. At the time React was what I knew, and I was coming off the back of building a server side rendered React site when I joined this company. I had a team of JavaScript-focused engineers to work with.

(comment deleted)
God. I wish my team did this. So much sunk cost.
I once led a project that had an android app years ago. Someone on the team brought in guava for a small number of helper utilities. This made our apk exceed the method limit which required some partitioning (forget the details) that increased the time to push the app from like 15 seconds (which was still way too long) to a minute (which I found unbearable).

One day I ripped out guava, handwrote the parts we were using and got our apk size safely within the method count limit. The project still failed horribly though but for other reasons :)

What to do when your 3 years of work is already written in Shitty React™?

I've been suggesting codebases cleanups but we only do it when the clients complains about severe bugs (which, hear hear, are due to our known core issues)

Reading this sort of stuff makes me reevaluate my life choices.
> I don't understand the 'techo side' of the story Dan, but the leadership is key, well done mate.

I find this comment by user "Dad" very endearing.

Ha! Good catch, I totally missed the "Dad" username when I read that comment. That's adorable if actually true
Author here. It’s actually my Dad!
Something doesn't really add up with the timelines in this story. I launched my own Angular2 site with SSR in the summer of 2017.

There were some rough edges, but it only took me a few days of hacking to get it working. Thankfully, the ecosystem is much better today

I think the difference might be that you knew what you wanted to build. That's usually the bigger issue in projects like this.

The other thing I can think of is that small teams or individuals can often outpace larger teams, at least when it comes to pure software development - in practice, a team handles things like 3rd party integrations, customer feedback, stakeholder management, demos, etc as well.

Author here. I agonized over the dates in the post when I was writing it. It’s correct to the best of my knowledge, but details fade with time.

I’m glad you had an easier time than we did!

The js ecosystem is frustrating. I’m a backend/DevOps/platform engineer so I don’t write frontends, but I’ve spent many hours working with and optimizing the compiled JavaScript in CI/CD pipelines, deployment systems, and homebrew bespoke SSR Rube Goldberg micro services that a backend calls out to, waits for the js to comeback, throws in a redis cache, then sends down the pipe to the user. The frustrating part is that often times the clusterfuck required to spit out some scripts that make Ajax calls to a backend, shuffle divs around, bind dom events, and push browser state, is so much more complicated than the backend systems that are actually doing the core work for the app.

SSR was a solved problem before SPA/huge frameworks became the often unnecessary de facto, standard. Why am I dealing with a backend app server that is deadlocked and exhausted its connection pool causing cascading failure because its (wrongly) making in-band calls to a micro service someone wrote which is a single threaded node app running a virtual dom and spitting out js that shouldn’t be required to serve up the app’s presentation layer, yet now is queuing up an ever increasing buffer of connections from the backend trying to get the page assembled to send to the user who does not care about any of the js so long as when they click shit, it clicks.

Js is a simple and small language. The runtime it executes in is designed for a very specific deployment target and even there it’s at its limits. Why did we let a tiny scripting language become this beast of complexity and obnoxiousness? Why can I put bundle optimization and tree shaking on my resume? Or that I inherited and maintained a not invented here fueled SSR system that would rehydrate Apollo stores and glamorous styles, for a site that would have looked the same and provided the same FE functionality using bootstrap css and js? Why am I adding extra headers to response bodies to debug if SSR is being cached by the backend properly, or if the caches are being busted properly and sweeping down the Russian doll layers at the react component level? Why, if it was known from the start that search crawlers wouldn’t render JavaScript, and as a result wouldn’t render the content you want indexed, did you not use a friggin backend templating engine that every MVC framework has a million options for, and include a damn partial that adds your js for a signup modal and some Apollo gql queries? All this complexity is for what? Bash is a tiny scripting language with very specific deployment targets and handles mostly presentation and in the what, 60 years it’s existed, shipping a shell script has been as simple as scp’ing a file to a server, which is how easily you used to be able to “build” and ship js. If the Linux OS devs didn’t need that kind of complexity, your hot or not site doesn’t either (: Is your job as a front end developer significantly improved from the days of using jquery or some other tiny no nonsense utility lib? I see the js being written and I don’t see a huge quality of life improvement to justify the chaos these systems introduced to the entire stack, build system, CI system, deployment orchestration, bundle optimization, library bloat and security upkeep, dependency hell for package upgrades, CVE shit show and supply chain security. What is your app doing that all of this is needed, for presentation? Modern web apps are enormous, render slow as hell, and often break expectations set in stone 20+ years ago, like the back button doing what it says on the tin, or inspecting a dom element and being able to actually see the content, not off in some store somewhere and bound to some property event that injects it and removes it as needed.

People have just accepted that this is how FE dev is done now, with jr devs knowing only this insanity and not anything else. I try to delude myself to think that this is fine, it’s better, somehow, and yes I realize that modern frameworks are in some ways better, react components are modular,...

As someone who has been doing frontend, backend, systems administration and general black magic since before the jquery days, I can tell you that managing frontend requirements was absolute hell back then. You literally had to put the script and style tags in the right order in your header or footer and just kind of hope the timing worked out. People how work exclusively on the backend tend to underestimate the complexity of frontend builds in the same way that non-technical people underestimate the complexity of all software engineering. The truth is, something as common as an autocomplete input is an application unto itself, with multiple dependencies all with load priorities. I don't have to imagine what this was like back in the jquery era, because I experienced it and it sucked.

I noted this earlier in the thread, but the fact is that any user-facing application with a UI is going to include JS/TS and CSS, and therefore is going to include a frontend build of some kind. Any build included in an application comes with the requisite build orchestration for all environments, so Docker config, build specific config, CI config, etc. If you add a second language to an application, you add a second build, and the cost of setup and maintenance of your application basically doubles. Not only that, you now have to have engineers proficient in multiple languages on your build. Most engineers are really haughty about the language they write and the part of the codebase they prefer to work on, so finding someone who is equally comfortable AND proficient writing python applications and frontend code is extremely hard. Most likely you'll get a Python engineer who will reluctantly write some awful React and complain about the entire time, or vice versa.

So if you come to me and try to add some Python or Ruby or god help you PHP to my single build Node/React application because you think its somehow going to make things simpler, I will simply eject you into the sun.

I'll write an API in any language that makes sense for the performance requirements. But if the app has a UI, absent any legacy requirements that force you to do otherwise, it 100% absolutely has to be entirely in JS or TS or you are shooting yourself in the foot.

> The React site would be functional and performant in 6 weeks, and ship in 10. If it didn't, I would step down and recruit a replacement.

I lost at lot of faith in the author's judgment at this point. I know this thing worked out and it was the right decision to port things over to React (and correct the bad decision to count on the Angular team to deliver SSR on their timelines). But you need to be able to explain things to the business without this sort of nonsense. I would be really concerned if I heard a manager saying something like that. It's not an argument, it's just a "trust me" that raises the stakes and pressure around the project.

That part worried me, too. The inherited situation was not good, but I think it may have set the stage for some reactionary heroics that were also somewhat unhealthy.

Jumping from one extreme (completely broken development process) to another (threatening to voluntarily resign if arbitrary deadlines aren’t hit) just feels like a sequence of unhealthy extremes driven more by ideology than practicality.

It’s great that the process worked out, but I’d not be happy to work under either team to be honest. Plenty of teams manage to ship working code without either of these problems.

> Plenty of teams manage to ship working code without either of these problems.

The key point is that the team in this story didn’t. They needed something extreme to make progress.

And remember that nearly all deadlines are arbitrary. Somebody needs to pick some date to see if something gets done by that date. There’s nothing wrong with an “arbitrary” deadline like the one described in the article.

I don’t agree at all that they needed the extreme behavior to make progress. They did need to bail on their bad plan and implement a better one.

> Somebody needs to pick some date to see if something gets done by that date.

Right. What you don’t need to do is say “I am going to hold my team to the arbitrary date I ballparked because I staked my reputation on hitting it no matter what”. That’s a miserable way to work.

(comment deleted)
I think you're taking things without knowing the details of his context. You speak to business in the language business understands. Sometimes business is not interested in your logical explanations. They're seen as excuses. Business dumps the responsibilities on your lap, gives you a budget, and starts pressuring you to deliver. The only conversations you then have are about time and money. Give me some time, give me some money, I'll save you more, etc. So those are the bottom lines of any arguments. Maybe in his specific case this (second) argument, of putting his job on the line to buy himself 10 weeks of work, combined with the first (staying aware of how the angular project is evolving and picking whichever comes first) was something that business felt comfortable risking. You would go in with all your React technobabble and be surprised when they roll their eyes and say "how long, how much".
I clicked into the author's profile and it says "Osaka, Japan" -- if that's the working environment, I wouldn't be surprised if that's the only approach that made sense given the intense work culture in Japan (from what I've heard)
I would argue that the stop loss (ship react in 10 weeks and step down if not) is misleading. What it really means is it becomes someone else’s problem. That someone else is management and the team, and simply put, no longer yours.
Yawn. Not another one of these "I came in and created the all the success."
(comment deleted)