3 ms·
> I used to dislike Next.js but it's grown on me considerably. Give Astro.js a spin. Notably, take a critical eye to the HTML and JS output of Astro.js vs Nex
by CharlieDigital 4y ago
> I used to dislike Next.js but it's grown on me considerably.
Give Astro.js a spin. Notably, take a critical eye to the HTML and JS output of Astro.js vs Next.js.
> I'm having a hard time imagining what this could possibly be
Think of something as simple as whether a div element is highlighted or not by simply adding/removing a CSS class name. In our case, it's a price tile like you'd see on Target.com. For this piece of functionality, there is a huge mountain of JS (also comprising the state) since we need to manipulate the object model to get the correct behavior when we conditionally render a class name. In vanilla, one might just do something like this and have a general purpose selection behavior:
const $ = (selector) => document.querySelectorAll(selector)
function select(evt) {
$("li").forEach(li => li.className = "")
evt.target.className = "selected"
}
$("li").forEach(li => li.addEventListener("click", select))
https://jsfiddle.net/84b5rhpk/2/ https://jsfiddle.net/84b5rhpk/2/
Another version with super simple option-detail selection: https://jsfiddle.net/84b5rhpk/3/ https://jsfiddle.net/84b5rhpk/3/
Even cleaner V3: https://jsfiddle.net/7szur3ex/ https://jsfiddle.net/7szur3ex/
This code is incredibly fast; requires no compilation, it's highly reusable since it cross cuts the DOM structure using `querySelectorAll` (I can reuse this function to select anything), easy to understand, has no dependency on the underlying data model, and it is stupid easy to debug. A developer doesn't need to learn the quirks of a framework or library to do this.
You might make the case that "well, a lot more things are also happening when the user makes a selection", but I'd offer that almost all of the side effects would be easier with vanilla in our case.
- DangitBobby 4y agoAh yeah, React doesn't make this any easier. You'll probably end up with a useState combined with className={clsx(selected[idx] && "selected")} or something. I don't think that's more complicated or even more LoC but it's definitely doing more work than vanilla so the performance difference is inarguable. You'd have to box off the state to its own component to avoid re-rendering the entire list.
- CharlieDigital 4y ago> I don't think that's more complicated or even more LoC but it's definitely doing more work than vanilla so the performance difference is inarguable It's not just the LoC, - I don't need a build chain for this; there's no transpilation. - I don't need an external library to download to the client to do this. - I can get the HTML from anywhere. Rails, PHP, Node.js, ASP.NET, static bucket in S3. Anywhere; I have more flexibility on my backend to pick something that's fast. - It's incredibly fast in the browser and SEO friendly *without any extra work* because all of the HTML is already sitting there. - I didn't need any rehydration or complex data flow/data passing logic from server to client. - It's easily debuggable even in production An even cleaner version: https://jsfiddle.net/7szur3ex/ https://jsfiddle.net/7szur3ex/ This is like 95% of the interactivity needed on an e-commerce PDP in 15 lines of JavaScript.
- DangitBobby 4y agoYou might be moving the goalposts slightly. The original comment said there were things you can do in a handful of lines in vanilla that it takes dozens of lines of React because you were concerned about complexity. Setting up the project should not be part of that complaint [if you guys have to set up the project every time you try to add a class to a selected item, I can understand why that would be cumbersome ;) ]. Vanilla JS tool chains being comparitively less complex and emitting smaller builds is not the line of discussion I thought I was engaging.
- CharlieDigital 4y agoYou don't have to set it up every time, but many features require that you tweak the setup and/or migrate your setup/configuration. I can't imagine having to tweak <script src="..." /> Rather than moving the goal posts, I'd proffer that you are missing the forest for the trees. Case in point: Next 12 to Next 13. The architecture of layout pages, client vs server only components, new build chain (surely will have its own kinks and bugs to iron out). Then there will be a Next 14, TurboPack 2, React 19, etc. Migrating some remaining systems from Node 12/14 to Node 16/18 and updating our CI configurations, local dev environments, and praying that all the packages update without issue. Breaking changes in upstream NPM packages. React's shift from class components to functional components and hooks. Working on integrating InstantSearch into a Next.js app this week and the `useClearRefinements` hook can't be included on the server side (despite the fact that our SSR is broken right now). So I needed to use `next/dynamic` and exclude it from SSR to get it to build which seemed extra ridiculous because... As I mentioned, this week, I noticed that our SSR pages were suddenly no longer generating any HTML on the server essentially turning our Next app into a full CSR app with server side API calls. I checked in with CTO and FE dev to see if this is intentional or accidental. Something errant with the toolchain, configuration, or change in how we are loading assets is now causing Next to misbehave (haven't figured this one out yet). I will never, ever have to deal with this with those 15 lines of JS. Those 15 lines of JS will never need to be migrated into a different runtime, build process, tool chain, or stack. 10 years later, those 15 lines of JS are still going to work. Whatever migrations you need to do to modernize your toolchain and stack over the next two years is work and effort that you're not spending on creating value. So the tool chain creates its own complexity that is secondary to the core development complexity. That's Alex Russell's point in the article: the complexity merchants have created an environment where there's so much unnecessary complexity and -- wouldn't you guess it? -- they have just the thing you need to solve it! They have you on a treadmill while they're feeding you doughnuts and chocolate.