> We ran into an error which took us 2 days to track down to a library, and you may find the same.
Fun times! Preact is React until it isn't. No reason to assume that won't happen again, by the way.
Once upon a time I had some people who wanted to include Preact because it's so small/dependencies/etc. Then they bitched because it wasn't React. Ay yi yi.
> One important piece of context is that Etsy currently has two major product stacks. For buyer-facing pages, we use PHP server-based rendering with jQuery/vanilla JS on the client to stitch things together. For our seller-facing pages and many of our internal tools, we use React-rendered SPAs with minimal server-based HTML rendering, receiving data from the same PHP server-side stack.
The unreasonable effectiveness of PHP
[EDIT] Just to add content to foster actual on-topic discussion —- is it likely that Etsy will be the only ones taking this off-ramp from React proper? Seems like the v15 -> v16 jump is onerous
I think it's more about the level of interactivity that is "needed". The seller part of the platform would do a lot of customization and changing settings, some of those probably have live previews as well, whereas the seller part of the platform is pretty static, no need for the same level of interactivity, so doing it by manually manipulating the DOM is manageable.
I think it is more that they do not go the "everything must be React" route, that gives them an advantage in that part of the frontend. Way less complex than the whole react ecosystem and it's "components".
Early in its life Facebook Engineering marketed React as "you probably don't know what you're doing with the DOM and incurring all sorts of performance issues with your hand-written Backbone View code, let React do that for you". In truth, you only need a vDOM with a component interface once your view code passes a certain threshold of complexity, but it just gets used everywhere, and for the simplest things, as the go-to solution.
One thing that makes me happy to spend more time on backend stuff, is that I get spared this kind of stuff and just keep doing SSR as I have always done, with a little bit of JavaScript when needed.
The irony to see all JavaScript frameworks re-inventing SSR to deal with the performance problems to do everything on the client, specially mobile phones.
AMP was a clear signal of the extent to which mobile web development was seriously flawed that Google had to go to major content publishers and say "look, your frontend is trash and nowhere near concise enough on mobile in either layout or behavior, just use our transformation layer"
The old AngularJS was pretty horrible in my experience, but Angular 2+ was leaps and bounds better! As a "batteries included" framework i prefer it to the alternatives that one would typically consider for front end development instead: React, Vue, Svelte etc. (though i would pick Vue/Svelte for more lightweight sites and maybe React because of its ecosystem)
That said, it still is pretty heavyweight which can certainly be a drawback, but not too much so unless you get into the reactive programming libraries and such, at least when compared with the alternatives: https://medium.com/dailyjs/a-realworld-comparison-of-front-e... (this appears to be from 2020 though, someone should do a newer writeup)
For the enterprise'y projects that i've seen, Angular seems like a reasonably stable and dependable solution to use. That's in contrast to React, which has needed way more updates in packages that it needs for the typical web project, due to its more fragmented nature. Of course, this might be viewed as a nitpick, but GitHub dependabot seems to page me more for React projects.
Also, if you want to use TypeScript (which i might go for, but only in some projects), then in my eyes it integrates with it way better than, say, React or Vue. To me, using TypeScript in React just felt needlessly cumbersome, especially with functional/hook based components.
When using React, i'd almost prefer to go for just JavaScript and enjoy the incredible productivity of being able to introduce and compose components very easily, way better than Vue seemed to let me. Of course, i'm probably in the minority here, because i'd go for functional view components and class based parent/container/logic components, but maybe that's just my antiquated way of thinking.
Also to conclude my subjective post of sharing my views and experiences, MobX > Redux. It's just wonderfully simple and easy to use for state management.
Hooks have been similarly easy: React's core hooks auto-infer the proper types, and custom hooks built on them don't require any particular type-plumbing in my experience...
It's been a little while since i had to work in the React + TypeScript project (nowadays use Vue more often) so it's not fresh in my memory, but sure!
For starters, even your example shows the awkwardness somewhat, it is essentially the same as writing the following (if you don't need the interface elsewhere):
Suppose i want to add a new property: now i need to do it in two places (the interface definition, with either syntax). Want to remove one? Same story. Rename one? Sure, your IDE should let you do this, but the change is still necessary in two places. Why couldn't i do something like this instead (the answer is that the language is just not structured that way, but clearly having duplication for no good reason whatsoever isn't nice):
Contrast that with a pure JS implementation (which is bad because it doesn't tell you about the individual props or their types, but surely one can also imagine just a list of different prop parameters):
function Component(props) {
return ...
}
Of course, that's more of a nitpick, but the code often reads worse than Java does in my eyes.
Another thing that i disliked was working with union types, especially when you're stuck with loosely defined objects in a legacy codebase, where you can't always work with properly structured definitions of "this one thing is a union of BASE FIELDS but also ADDITIONAL FIELDS FOR ENTITY TYPE A that won't be defined in separate places, because if we split it up for some reason this one library integration will fail to render UI components properly".
I started writing out more about that particular case, but realized that articulating precisely what was the problem in it and diving back into that older codebase to recreate code examples would take time and sadly i don't really care for doing that. But hey, JavaScript would let you just wing it and check each field individually before trying to access them, so you could let the code decide the behavior, not the type system, which is sometimes the path of least resistance. Personally, i think that strong type systems are always good in the back end, but i feel less strongly in that regard about front ends.
Also, i'm not sure that building TypeScript on top of JavaScript was the best idea: surely from a support/target platform perspective it was brilliant, but sometimes you get all sorts of awkwardness.
For example, the React TypeScript bindings themselves have something like the following:
type Booleanish = boolean | 'true' | 'false';
Oh, and in regards to TypeScript in particular (though this is also annoying in Angular etc.), their implementation of even enums is awkward. Consider that in Java you can easily turn any string into an enum value if possible and can also have enums act as containers for additional data, for example: https://www.tutorialspoint.com/how-to-convert-a-string-to-an...
Mostly I have various stylistic misgivings with Angular. I feel like I spend a lot of time on ceremony and piles of RxJS that would've just been simple function calls in React, which is what I did before. There are some things related to state management, especially module initialization, that it seems to me is a leading to a lot of code bloat to handle an initial state with null state that shouldn't actually ever exist, but that might be user error.
More acutely, though, since upgrading to version 12 a few weeks ago, build times have run into several minutes (most of it spent in the "Sealing" phase), and it's developed a habit of crashing the dev server process due to running out of heap (on 16GB machines). We've tried various suggested workarounds and they work for some of our devs, but not for me. The past week or so even a single character change means waiting for the dev server to run out of heap, then restarting it and waiting for a complete rebuild. This takes several minutes all in all and requires manually restarting the server in the middle of it.
I tried addressing the issue but I couldn't find a solution that actually worked, so I tried to upgrade to Angular 13 in the hope that it might go away. That took a day to just get it to build, but then I couldn't get our application to start. So now I've put off upgrading, which is obvs also a worrying prospect.
We're an early stage start-up in the middle of a major crunch and it's frankly a bit of a nightmare. I've been keeping busy in other parts of the stack as best I can, but as you can imagine that's really not what a three-person team needs.
Is this the fault of me, my lack of knowledge of Angular internals, and our messy code base? Most likely! But I did years of React before and I was never in such a mess. I also find the Angular build system quite hard to understand and debug and I'm not entirely sure what the benefit is. Something about server-side rendering? IDK. I do some Elixir/Phoenix in my spare time, I feel like I get 99% of the functionality there for 1% of the effort (and machine resources).
We're going to need to bring in outside help if I don't crack it in the next few days but I'm frankly not really sure what the budget is like. Fun times!
Heh, this seems like a case of different people having completely opposite experiences.
Had to work on an Angular project or two, they were largely passable and didn't cause too many problems. Admittedly felt a bit close to writing back end code at times, even - pretty boring and predictable. In Angular the type system was also reasonably easy to use, even with things like non-nullable/nullable/optional values etc.
Had to work on a few React projects, the JavaScript ones were pleasant to work with and develop (seriously, React's functional components are an amazing time saver for display components), but as soon as you introduced TypeScript and Redux as well as plenty of hooks and even custom hooks, it went down the drain.
Perhaps that's a bit what you're experiencing with RxJS, which adds a ton of complexity in of itself - being able to start with just Angular and go from there (or in my case - using MobX instead of Redux which is just so much nicer to use) might have been more passable.
The only way is rewriting the front-end in a different framework. If you can, you probably should do it all at once.
If doing it all at once is too much work, you can look at web components as a technology to have both in the same page. Angular elements allows wrapping angular code and putting it inside another framework. Angular also makes it easy to embed web components into its pages, so you could rewrite piece by piece in a framework that supports creating web components, like vue.
The real challenge with the piece by piece approach is managing data flow and component lifecycle across the frameworks, and doing that requires codebase-specific solutions.
I've helped teams move from Angular to web components. It's much easier than any other alternative. The data flow just works in Angular 2, though sometimes requires a directive in Angular 1.
I lead a project that did an in place rewrite from angular to react while still shipping new features. We wrote an angular -> react shim so that we could render react leaf nodes. We worked down the angular stack replacing increasingly lower level components. We had a cut over date of no new angular code, then essentially a code freeze for a month or so to do the rest (routing, data store). This project took 4 or maybe 5 months, but the resulting velocity on the other side more than made up for it.
Interesting to know it can be done. We're probably not at a place where we can consider it, but it would be nice to plan for. Can you tell me more about your Angular -> React shim?
For some reason, this code [1] is still accessible on the public internet! This dates back to CoreOS and the Tectonic (CoreOS's k8s distro) Console. The code needed to be rewritten, I had familiarity with React, and after the nth time Angular 2 broke backwards compatibility in an RC, we went for it.
It was a little different than I remembered. We moved all data into Redux and piped it into the various Angular bits. Then, it was a matter of making the angular-> react bridge (using ngreact) introduced in this PR.
Do it incrementally, if you can. I started migrating to react by making new components in react and embedding them with ngreact. Yeah, angularjs and not angular, but the concept holds.
One thing I don't understand about the JS ecosystem in general is the focus on minified size. This article does the same thing: preact is 6k or so whereas react is 36k.
This comparison seems entirely pointless when the first page load downloads multiple megabytes of assets and, additionally, a lot of users would have React in their browser cache anyway.
Speaking from building both react and Preact sites serving millions of customers - the difference is noticeable when you add everything up.
Minification or not, starting with a 6x bundle size puts you in a precarious position to have to care more about how it grows over time adding other assets.
Downloading, parsing and then executing a larger bundle size will impact performance and we've been able to see time to interactive impact conversion on e-commerce sites. However you are right that there are many other factors at play here that will make the site better and I think the post misses the point about "bundle size".
The important differentiation for us with Preact is two things: native support for web components, and a significantly faster library when it comes to transformations and dealing with vdom - see here https://rawgit.com/krausest/js-framework-benchmark/master/we...
On your comment about browser cache, also true but it really depends - if you haven't appropriately split out your bundle then returning users will probably be redownloading react again and again with app updates. Also new users are super important because if you are trying to get new traffic you care about their experience not just returning users.
> Minification or not, starting with a 6x bundle size puts you in a precarious position to have to care more about how it grows over time adding other assets.
If this were true, wouldn't it apply in equal measure to other resources?
And if that's true, then why do we still see multiple MB large pages that are full of images or even videos? Personally, the arguments expressed in "The Website Obesity Crisis" back in 2015 still hold up today in my eyes: https://idlewords.com/talks/website_obesity.htm
In short, for me to agree with your argument, i'd have to see websites in general take the path of using less images when not necessary, or optimize them better and use slightly lower resolutions etc.
Opening the first random news site that came to mind, BBC, yields over 5 MB of data and almost 100 network requests: https://www.bbc.com/
Opening Reddit means almost 15 MB of data and has around 235 network requests: https://www.reddit.com/
Opening YouTube means almost 12 MB of data and has around 90 network requests: https://www.youtube.com/
Sure, there are techniques to minimize this impact and compression that everyone should be using for their content, but if the big companies are doing something like this, then clearly the majority of people don't really care. To me, it feels like the thing that we should be doing is just putting less content in pages, less functionality, less widgets etc.
It needs less than 3 MB of data to load and while around 90 network requests is still bad, as a consequence of the smaller size, it loads more quickly!
(note: the imporance of compression cannot be overstated, but at the end of the day even if your 15 MB compresses down to 5 MB, your browser still needs to handle all of that stuff locally, process the JS, CSS and HTML and display all of your media anyways, as well as keep it in memory, so i'd say that both the full size and the compressed size matters, decreasing the former obviously being good for the latter as well)
> If this were true, wouldn't it apply in equal measure to other resources?
No. On sites that buy in to react/preact, there are parts of the site that won't work until react/preact has loaded.
In contrast, the site will work perfectly fine without having loaded those large beautiful images. If done correctly, images won't even affect the layout of the page.
Likewise, it doesn't matter if google analytics and the 10 thousand myriad tracking pixels take a minute to load: users shouldn't notice any difference here.
> but if the big companies are doing something like this, then clearly the majority of people don't really care.
Companies are complicated beasts. Using react or preact is entirely a predicament of the technical team. Nobody from marketing, sales, business could care less about it.
However, marketing _needs_ (that's how they put it) those myriad tracking pixels because otherwise they can't track the effectiveness of their campaigns.
Corporate wants those custom fonts and beautiful, large images because real people have said the site looks much better with them in usability tests (done using enterprise-level network connectivity of course).
Sales people will go to war over having analytics, as otherwise they don't know how effective their campaigns are, and business loves the nice dashboards there so they back them up.
The tech team decides that given the pace at which complicated interactive features are coming in going the plain html + sprinkle of vanilla javascript is untenable (partly due to whats-cool-today syndrome).
In the end you get these big, "bloated" sites as a result. What users actually want is just a small factor in all this.
> Likewise, it doesn't matter if google analytics and the 10 thousand myriad tracking pixels take a minute to load: users shouldn't notice any difference here.
So much for me being able to open 100-200 tabs across all windows on my browser without needing more RAM.
Or even using a browser on my older phone without it feeling slow/sluggish or the browser killing the battery life of the device.
To clarify for the downvoters: my point is that it might not matter for the average user for whom the site is optimized, they might be able to tolerate ads, autoplaying videos, popups, incredible waste of resources just to get visually attractive UI etc. and be none the wiser about any of it (possibly not even knowing that things could be different), but it definitely matters for people who want more out of web in regards to usability.
In my eyes, there's little difference between the current state of web and using Electron for desktop applications instead of native solutions, both seem to be driven by financial initiatives and result in a degraded experience, playing directly into Wirth's law and thus making interfacing with computers worse as a whole (though admittedly the state of the web feels more malicious than a team wanting one Electron codebase for multiple platforms).
Hey, I said "users", not "evil hackers doing weird things" ;)
The sad thing is that this isn't entirely a joke. I've brought up those kind of issues in executive meetings in the past (trying to exterminate battery-draining animations being a particular crusade of mine).
The response is a mix of blank stares, mild interest... and a quick dismissal from the top dog in the room, along the lines of: "That's certainly something to consider, but I think we have more pressing matters in our hands. Let's keep these on the back burner."
I've definitely run into this in my own past as well. On one hand, you can understand the business incentives - ship something relatively quickly, have it look good enough to attract attention or at least not scare anyone away.
For example, compare the front pages of SourceHut (a lovely and lightweight project) https://sourcehut.org/ and GitLab (a really good self-hostable solution with plenty of features) https://about.gitlab.com/
One of those would capture the attention of most people better, so that's what the market will optimize for at large, unfortunately also sometimes pushing focusing on other things with less visibility (to the average user) to the back.
For the simpler things, not asking for permission can be a good idea (depending on the environment and circumstances) - a line that i heard in a software development conference once was: "You don't ask your manager for permission to write tests for your code, so why should you for making other similar decisions that are essentially just doing your job well?"
Of course, then you also become responsible for the potential impact of those changes and things going wrong, so it works better on simpler cases/optimizations and only as long as the things you're changing are simple enough to have almost no impactful bugs or you have enough tests in place to catch any.
Other times you can succeed by adopting a data driven approach and a healthy helping of taking initiative: "Hey, our automated performance tests indicate a regression in page load times of X% after version Y, which, according to these random but serious looking studies and posts might result in lost potential conversions and could cost us Z$ the following year. I've described these problems and what to do in Jira issue #W and have escalated the priority to 2, so that's what i plan on doing this week. Any questions?"
Maybe I should have been clearer with me follow on paragraph where I talk about parsing of JavaScript and downloading of that - rather than all other assets. I agree with you that the web is broken and that we send way too much to the client in the first place.
However, there are many ways of mitigating additional assets getting in the way of both being able to interact the site and see it within a reasonable amount of time. We look at this through the lense of performance, where downloading some assets in the background might not necessarily harming your experience.
That's not to say we shouldn't be optimising for the smallest amount of network requests a site should make and think carefully about when to load images in. Your examples are what bad looks like and it's a shame, but there are now more and more sites that do a stellar job (or starting to) of giving you a great experience with less downloaded.
However if you were to download a 5mb image asynchronously that isn't part of your initial above the fold, Vs a 5mb payload of react that's needed to run the site... I know which one is going to make your browser a very unhappy bunny.
> the first page load ... a lot of users would have React in their browser cache anyway
Not on the first load. If you mean that it will be cached from other sites through the same CDN, then that's also unfortunately not true anymore since cache partitioning [1].
As sibling comments mention, cache partitioning means there's no way for react to be shared, but even without cache partitioning react apps are usually bundled into 1 file with all the dependencies inlined, which stops caching from being useful across sites anyway.
Yeh, I read most of the article looking for more advantages of Preact other than just reduced bundle size but that seems to be basically it, or at least all that the write up covers. Did I miss something?
The way people bundle React with the rest of the user code on its own domain, 0% of the users would have React on their browsers already. It was already not true for the vast majority of jquery and this is a myth that should die/a reality that never happened (I cannot seem to find the article with the study now to prove it though...).
The other comments hit some spots (although today with the use of bundling, I'm not sure caching matters as much as people make it out to), but something that is currently missing from the conversation: parsing performance. Not the speed that the browser fetches the .js file (which depends on network quality) but rather the speed the browser parses the actual code, which can sometimes become the bottleneck. Larger projects adds more code for the browser to parse, and that will make the initial page-load performance worse. Smaller scripts === faster page-load, which improves user-experience and all metrics related to that.
> a lot of users would have React in their browser cache anyway
Not cross-origin, anymore. Every major browser now has cache partitioning (cache indexes are keyed by the requesting domain and the resource) for privacy reasons. Which means, for instance, the old optimization of using dependencies from a CDN is now suboptimal.
I'm guessing almost no one benefitted from cross-origin caching with React anyways, since it is almost always bundled up with Webpack. It's not like jQuery or Font Awesome.
I’m not sure I could quantify it, but CDNs were a prominent recommendation for React at least until CRA was pervasive.
Another thing worth mentioning, and another point in Preact’s favor, is ESM and tree-shaking. React still doesn’t officially ship ESM, and the ability to strip unused functionality at build time is hampered by that because ESM is more amenable to static analysis. Whereas Preact, which is already much smaller on the wire, can become smaller still because it supports ESM.
- It definitely shouldn't be downloading multiple megabytes of assets, at least not blocking assets. A reasonable primary JS bundle size (including the framework and other dependencies) is around 150kb; 30kb would be 20% of that. Images, marketings scripts, etc. are excluded because they don't block rendering/interactivity; the browser generally knows to defer those until after the main experience has loaded. The core bundle, on the other hand, blocks rendering content (if it's all rendered client-side) or at least interactivity (if content is rendered server-side and then hydrated client-side). And on top of just the download time, there's the time it takes the browser to parse and compile the code. So yeah, every few kilobytes matter.
- Virtually nobody would have React in their browser cache from a re-usable URL. That was common in the jQuery days, but that's not how things are done today. For better or worse, a modern JS app bundles all of its dependencies statically in a self-sufficient bundle (possibly "chunked" into multiple files, but all domain-local). You could technically do things the old way, but you'd be fighting the tooling and ecosystem at every step. And anyway, your users probably wouldn't benefit from cache hits because no other sites are doing it. There's a hypothetical future where ES modules take off enough that dynamically loading dependencies becomes feasible and popular again, though even then, there are benefits to static bundling (like tree-shaking) that some probably wouldn't want to give up.
You clearly didn't read the article. It mentions that in addition to the (relatively small) bundle size savings, the version of Preact they were investigating (as of 2020 when it was written) was also more compatible with the current version of React they were using at the time than the newest version of React (15 -> 16 had a lot of breaking changes). I don't believe the bundle size was really a major contributor to the decision honestly.
> While it would be really hard to describe here in detail all of the new features, the code architecture improvements enabled by the React v16.8 Hooks functionality are so significant that it will eventually become harder and harder to recruit developers interested in working in a pre-Hooks codebase. In order to keep up with the rest of the industry and provide our current developers with the best tooling available, I believe it should be a high priority to enable use of Hooks and other modern React functionality. This definitely isn’t anywhere close to the only new feature worth upgrading for, but it does represent an extremely large shift in how developers will be able to write React code.
There were almost no significant breaking changes between 15 and 16, the chances of an app even using one of the few APIs that changed was very very small..
Rather, their dependencies seem to have had breaking changes for some reason when updating those versions. I don't know, that's what the article claimed.
You clearly didn't read the HN guidelines, judging by this and your other comments.
> Be kind. Don't be snarky. Have curious conversation; don't cross-examine. Please don't fulminate. Please don't sneer, including at the rest of the community.
I wonder what the other differences and considerations are. The article is focused on issues that might arise from switching, but does not really cover the “why” of switching beyond bundle size. A valid reason, but I assume there is something to say for React or is it really that similar that switching is a no brainer?
The way I read the document is that the main reason is that they do not have to upgrade their whole stack including dependencies like React Router.
Stepping off the dependency upgrade treadmill is an interesting and valid point that I think many HN readers dream of. It seems to me that Etsy has ended up so far behind current React that going to Preact is a very valid direction to take.
I also don't see why switching to Preact does not require updating, they even mention they will have to do this anyway, including some of their routing dependencies. Preact seems to be keen on keeping compatibility with React, referring to the current and previous versions, so it is very likely updates need to happen regardless.
Also, upgrading React is usually not too much effort as for most changes codemods are provided that do most of the work. Not saying it doesn't require effort at scale, but I don't see or read how Preact would make that any easier. Considering you'll use React libraries in Preact I would be worried about upgrading and compatibility later on.
I'm honestly interested as the lower bundle size is significant, but I'd like to know the other pros/cons and risks that surely are there.
I think the biggest problem with this is that Preact is not a 100% drop-in replacement for React. The devil is in the details. The programmers will casually follow online answers from stackoverflow or blog post regarding React and apply them to the Preact project. This will work more often than not, but from time to time you can run strange bugs, which only happens on Preact and it takes much time to detect and debug them.
I built a product with Preact, and can’t think of any time it’s bitten us like that. I’m sure you’re right, but for us at least, it’s been smooth sailing.
70 comments
[ 4.7 ms ] story [ 135 ms ] threadFun times! Preact is React until it isn't. No reason to assume that won't happen again, by the way.
Once upon a time I had some people who wanted to include Preact because it's so small/dependencies/etc. Then they bitched because it wasn't React. Ay yi yi.
Every time I migrated a client most engineers didn't even notice and you just saved shipping a heavy bundle.
Compatibility is really good, most third party components work and the few which don't are covered by alternative implementations.
The unreasonable effectiveness of PHP
[EDIT] Just to add content to foster actual on-topic discussion —- is it likely that Etsy will be the only ones taking this off-ramp from React proper? Seems like the v15 -> v16 jump is onerous
Then the hydrations costs on the client typically start at 500ms, and that's 500ms the main thread could be doing something useful with
It's feels almost as if... PHP was made for this web stuff. What a lucky coincidence!
The irony to see all JavaScript frameworks re-inventing SSR to deal with the performance problems to do everything on the client, specially mobile phones.
The old AngularJS was pretty horrible in my experience, but Angular 2+ was leaps and bounds better! As a "batteries included" framework i prefer it to the alternatives that one would typically consider for front end development instead: React, Vue, Svelte etc. (though i would pick Vue/Svelte for more lightweight sites and maybe React because of its ecosystem)
That said, it still is pretty heavyweight which can certainly be a drawback, but not too much so unless you get into the reactive programming libraries and such, at least when compared with the alternatives: https://medium.com/dailyjs/a-realworld-comparison-of-front-e... (this appears to be from 2020 though, someone should do a newer writeup)
For the enterprise'y projects that i've seen, Angular seems like a reasonably stable and dependable solution to use. That's in contrast to React, which has needed way more updates in packages that it needs for the typical web project, due to its more fragmented nature. Of course, this might be viewed as a nitpick, but GitHub dependabot seems to page me more for React projects.
Also, if you want to use TypeScript (which i might go for, but only in some projects), then in my eyes it integrates with it way better than, say, React or Vue. To me, using TypeScript in React just felt needlessly cumbersome, especially with functional/hook based components.
When using React, i'd almost prefer to go for just JavaScript and enjoy the incredible productivity of being able to introduce and compose components very easily, way better than Vue seemed to let me. Of course, i'm probably in the minority here, because i'd go for functional view components and class based parent/container/logic components, but maybe that's just my antiquated way of thinking.
Also to conclude my subjective post of sharing my views and experiences, MobX > Redux. It's just wonderfully simple and easy to use for state management.
Out of curiosity: can you explain how/why? My experience has been quite simple, especially if only using functional components and hooks:
Hooks have been similarly easy: React's core hooks auto-infer the proper types, and custom hooks built on them don't require any particular type-plumbing in my experience...For starters, even your example shows the awkwardness somewhat, it is essentially the same as writing the following (if you don't need the interface elsewhere):
Suppose i want to add a new property: now i need to do it in two places (the interface definition, with either syntax). Want to remove one? Same story. Rename one? Sure, your IDE should let you do this, but the change is still necessary in two places. Why couldn't i do something like this instead (the answer is that the language is just not structured that way, but clearly having duplication for no good reason whatsoever isn't nice): Contrast that with a pure JS implementation (which is bad because it doesn't tell you about the individual props or their types, but surely one can also imagine just a list of different prop parameters): Of course, that's more of a nitpick, but the code often reads worse than Java does in my eyes.Another thing that i disliked was working with union types, especially when you're stuck with loosely defined objects in a legacy codebase, where you can't always work with properly structured definitions of "this one thing is a union of BASE FIELDS but also ADDITIONAL FIELDS FOR ENTITY TYPE A that won't be defined in separate places, because if we split it up for some reason this one library integration will fail to render UI components properly".
I started writing out more about that particular case, but realized that articulating precisely what was the problem in it and diving back into that older codebase to recreate code examples would take time and sadly i don't really care for doing that. But hey, JavaScript would let you just wing it and check each field individually before trying to access them, so you could let the code decide the behavior, not the type system, which is sometimes the path of least resistance. Personally, i think that strong type systems are always good in the back end, but i feel less strongly in that regard about front ends.
Also, i'm not sure that building TypeScript on top of JavaScript was the best idea: surely from a support/target platform perspective it was brilliant, but sometimes you get all sorts of awkwardness.
For example, the React TypeScript bindings themselves have something like the following:
Oh, and in regards to TypeScript in particular (though this is also annoying in Angular etc.), their implementation of even enums is awkward. Consider that in Java you can easily turn any string into an enum value if possible and can also have enums act as containers for additional data, for example: https://www.tutorialspoint.com/how-to-convert-a-string-to-an...More acutely, though, since upgrading to version 12 a few weeks ago, build times have run into several minutes (most of it spent in the "Sealing" phase), and it's developed a habit of crashing the dev server process due to running out of heap (on 16GB machines). We've tried various suggested workarounds and they work for some of our devs, but not for me. The past week or so even a single character change means waiting for the dev server to run out of heap, then restarting it and waiting for a complete rebuild. This takes several minutes all in all and requires manually restarting the server in the middle of it.
I tried addressing the issue but I couldn't find a solution that actually worked, so I tried to upgrade to Angular 13 in the hope that it might go away. That took a day to just get it to build, but then I couldn't get our application to start. So now I've put off upgrading, which is obvs also a worrying prospect.
We're an early stage start-up in the middle of a major crunch and it's frankly a bit of a nightmare. I've been keeping busy in other parts of the stack as best I can, but as you can imagine that's really not what a three-person team needs.
Is this the fault of me, my lack of knowledge of Angular internals, and our messy code base? Most likely! But I did years of React before and I was never in such a mess. I also find the Angular build system quite hard to understand and debug and I'm not entirely sure what the benefit is. Something about server-side rendering? IDK. I do some Elixir/Phoenix in my spare time, I feel like I get 99% of the functionality there for 1% of the effort (and machine resources).
We're going to need to bring in outside help if I don't crack it in the next few days but I'm frankly not really sure what the budget is like. Fun times!
Had to work on an Angular project or two, they were largely passable and didn't cause too many problems. Admittedly felt a bit close to writing back end code at times, even - pretty boring and predictable. In Angular the type system was also reasonably easy to use, even with things like non-nullable/nullable/optional values etc.
Had to work on a few React projects, the JavaScript ones were pleasant to work with and develop (seriously, React's functional components are an amazing time saver for display components), but as soon as you introduced TypeScript and Redux as well as plenty of hooks and even custom hooks, it went down the drain.
Perhaps that's a bit what you're experiencing with RxJS, which adds a ton of complexity in of itself - being able to start with just Angular and go from there (or in my case - using MobX instead of Redux which is just so much nicer to use) might have been more passable.
Actually made a sibling comment like this, though it's not as detailed as i'd like: https://news.ycombinator.com/item?id=30220131
But hey, good luck with bending Angular to your will! If nothing else, i can acknowledge many codebases out there being a mess!
If doing it all at once is too much work, you can look at web components as a technology to have both in the same page. Angular elements allows wrapping angular code and putting it inside another framework. Angular also makes it easy to embed web components into its pages, so you could rewrite piece by piece in a framework that supports creating web components, like vue.
The real challenge with the piece by piece approach is managing data flow and component lifecycle across the frameworks, and doing that requires codebase-specific solutions.
You can contact me on Twitter @ilDon_xyz
It was a little different than I remembered. We moved all data into Redux and piped it into the various Angular bits. Then, it was a matter of making the angular-> react bridge (using ngreact) introduced in this PR.
1. https://github.com/openshift/console/commit/4cc9c5d79f3fdea1...
This comparison seems entirely pointless when the first page load downloads multiple megabytes of assets and, additionally, a lot of users would have React in their browser cache anyway.
Minification or not, starting with a 6x bundle size puts you in a precarious position to have to care more about how it grows over time adding other assets.
Downloading, parsing and then executing a larger bundle size will impact performance and we've been able to see time to interactive impact conversion on e-commerce sites. However you are right that there are many other factors at play here that will make the site better and I think the post misses the point about "bundle size".
The important differentiation for us with Preact is two things: native support for web components, and a significantly faster library when it comes to transformations and dealing with vdom - see here https://rawgit.com/krausest/js-framework-benchmark/master/we...
On your comment about browser cache, also true but it really depends - if you haven't appropriately split out your bundle then returning users will probably be redownloading react again and again with app updates. Also new users are super important because if you are trying to get new traffic you care about their experience not just returning users.
If this were true, wouldn't it apply in equal measure to other resources?
And if that's true, then why do we still see multiple MB large pages that are full of images or even videos? Personally, the arguments expressed in "The Website Obesity Crisis" back in 2015 still hold up today in my eyes: https://idlewords.com/talks/website_obesity.htm
In short, for me to agree with your argument, i'd have to see websites in general take the path of using less images when not necessary, or optimize them better and use slightly lower resolutions etc.
Opening the first random news site that came to mind, BBC, yields over 5 MB of data and almost 100 network requests: https://www.bbc.com/
Opening Reddit means almost 15 MB of data and has around 235 network requests: https://www.reddit.com/
Opening YouTube means almost 12 MB of data and has around 90 network requests: https://www.youtube.com/
Sure, there are techniques to minimize this impact and compression that everyone should be using for their content, but if the big companies are doing something like this, then clearly the majority of people don't really care. To me, it feels like the thing that we should be doing is just putting less content in pages, less functionality, less widgets etc.
Case in point: https://old.reddit.com/
It needs less than 3 MB of data to load and while around 90 network requests is still bad, as a consequence of the smaller size, it loads more quickly!
(note: the imporance of compression cannot be overstated, but at the end of the day even if your 15 MB compresses down to 5 MB, your browser still needs to handle all of that stuff locally, process the JS, CSS and HTML and display all of your media anyways, as well as keep it in memory, so i'd say that both the full size and the compressed size matters, decreasing the former obviously being good for the latter as well)
On a similar note, there is a really interesting site called "What Does My Site Cost", which allows to further illustrate the bloat, for example: https://whatdoesmysitecost.com/index.php?testID=220205_BiDc8...
Back on topic, i think that Preact, Svelte and even Vue are all pretty cool lightweight options for front end development!
No. On sites that buy in to react/preact, there are parts of the site that won't work until react/preact has loaded.
In contrast, the site will work perfectly fine without having loaded those large beautiful images. If done correctly, images won't even affect the layout of the page.
Likewise, it doesn't matter if google analytics and the 10 thousand myriad tracking pixels take a minute to load: users shouldn't notice any difference here.
> but if the big companies are doing something like this, then clearly the majority of people don't really care.
Companies are complicated beasts. Using react or preact is entirely a predicament of the technical team. Nobody from marketing, sales, business could care less about it.
However, marketing _needs_ (that's how they put it) those myriad tracking pixels because otherwise they can't track the effectiveness of their campaigns.
Corporate wants those custom fonts and beautiful, large images because real people have said the site looks much better with them in usability tests (done using enterprise-level network connectivity of course).
Sales people will go to war over having analytics, as otherwise they don't know how effective their campaigns are, and business loves the nice dashboards there so they back them up.
The tech team decides that given the pace at which complicated interactive features are coming in going the plain html + sprinkle of vanilla javascript is untenable (partly due to whats-cool-today syndrome).
In the end you get these big, "bloated" sites as a result. What users actually want is just a small factor in all this.
So much for me being able to open 100-200 tabs across all windows on my browser without needing more RAM.
Or even using a browser on my older phone without it feeling slow/sluggish or the browser killing the battery life of the device.
To clarify for the downvoters: my point is that it might not matter for the average user for whom the site is optimized, they might be able to tolerate ads, autoplaying videos, popups, incredible waste of resources just to get visually attractive UI etc. and be none the wiser about any of it (possibly not even knowing that things could be different), but it definitely matters for people who want more out of web in regards to usability.
In my eyes, there's little difference between the current state of web and using Electron for desktop applications instead of native solutions, both seem to be driven by financial initiatives and result in a degraded experience, playing directly into Wirth's law and thus making interfacing with computers worse as a whole (though admittedly the state of the web feels more malicious than a team wanting one Electron codebase for multiple platforms).
The sad thing is that this isn't entirely a joke. I've brought up those kind of issues in executive meetings in the past (trying to exterminate battery-draining animations being a particular crusade of mine).
The response is a mix of blank stares, mild interest... and a quick dismissal from the top dog in the room, along the lines of: "That's certainly something to consider, but I think we have more pressing matters in our hands. Let's keep these on the back burner."
I don't even try anymore :(
For example, compare the front pages of SourceHut (a lovely and lightweight project) https://sourcehut.org/ and GitLab (a really good self-hostable solution with plenty of features) https://about.gitlab.com/
One of those would capture the attention of most people better, so that's what the market will optimize for at large, unfortunately also sometimes pushing focusing on other things with less visibility (to the average user) to the back.
For the simpler things, not asking for permission can be a good idea (depending on the environment and circumstances) - a line that i heard in a software development conference once was: "You don't ask your manager for permission to write tests for your code, so why should you for making other similar decisions that are essentially just doing your job well?"
Of course, then you also become responsible for the potential impact of those changes and things going wrong, so it works better on simpler cases/optimizations and only as long as the things you're changing are simple enough to have almost no impactful bugs or you have enough tests in place to catch any.
Other times you can succeed by adopting a data driven approach and a healthy helping of taking initiative: "Hey, our automated performance tests indicate a regression in page load times of X% after version Y, which, according to these random but serious looking studies and posts might result in lost potential conversions and could cost us Z$ the following year. I've described these problems and what to do in Jira issue #W and have escalated the priority to 2, so that's what i plan on doing this week. Any questions?"
However, there are many ways of mitigating additional assets getting in the way of both being able to interact the site and see it within a reasonable amount of time. We look at this through the lense of performance, where downloading some assets in the background might not necessarily harming your experience.
That's not to say we shouldn't be optimising for the smallest amount of network requests a site should make and think carefully about when to load images in. Your examples are what bad looks like and it's a shame, but there are now more and more sites that do a stellar job (or starting to) of giving you a great experience with less downloaded.
However if you were to download a 5mb image asynchronously that isn't part of your initial above the fold, Vs a 5mb payload of react that's needed to run the site... I know which one is going to make your browser a very unhappy bunny.
Not on the first load. If you mean that it will be cached from other sites through the same CDN, then that's also unfortunately not true anymore since cache partitioning [1].
[1] https://www.peakhour.io/blog/cache-partitioning-firefox-chro...
(and it was low with jQuery)
Do browsers share cache across domains? Seems like an easy vector to poison.
Not cross-origin, anymore. Every major browser now has cache partitioning (cache indexes are keyed by the requesting domain and the resource) for privacy reasons. Which means, for instance, the old optimization of using dependencies from a CDN is now suboptimal.
Another thing worth mentioning, and another point in Preact’s favor, is ESM and tree-shaking. React still doesn’t officially ship ESM, and the ability to strip unused functionality at build time is hampered by that because ESM is more amenable to static analysis. Whereas Preact, which is already much smaller on the wire, can become smaller still because it supports ESM.
- It definitely shouldn't be downloading multiple megabytes of assets, at least not blocking assets. A reasonable primary JS bundle size (including the framework and other dependencies) is around 150kb; 30kb would be 20% of that. Images, marketings scripts, etc. are excluded because they don't block rendering/interactivity; the browser generally knows to defer those until after the main experience has loaded. The core bundle, on the other hand, blocks rendering content (if it's all rendered client-side) or at least interactivity (if content is rendered server-side and then hydrated client-side). And on top of just the download time, there's the time it takes the browser to parse and compile the code. So yeah, every few kilobytes matter.
- Virtually nobody would have React in their browser cache from a re-usable URL. That was common in the jQuery days, but that's not how things are done today. For better or worse, a modern JS app bundles all of its dependencies statically in a self-sufficient bundle (possibly "chunked" into multiple files, but all domain-local). You could technically do things the old way, but you'd be fighting the tooling and ecosystem at every step. And anyway, your users probably wouldn't benefit from cache hits because no other sites are doing it. There's a hypothetical future where ES modules take off enough that dynamically loading dependencies becomes feasible and popular again, though even then, there are benefits to static bundling (like tree-shaking) that some probably wouldn't want to give up.
> While it would be really hard to describe here in detail all of the new features, the code architecture improvements enabled by the React v16.8 Hooks functionality are so significant that it will eventually become harder and harder to recruit developers interested in working in a pre-Hooks codebase. In order to keep up with the rest of the industry and provide our current developers with the best tooling available, I believe it should be a high priority to enable use of Hooks and other modern React functionality. This definitely isn’t anywhere close to the only new feature worth upgrading for, but it does represent an extremely large shift in how developers will be able to write React code.
> Be kind. Don't be snarky. Have curious conversation; don't cross-examine. Please don't fulminate. Please don't sneer, including at the rest of the community.
https://news.ycombinator.com/newsguidelines.html
Stepping off the dependency upgrade treadmill is an interesting and valid point that I think many HN readers dream of. It seems to me that Etsy has ended up so far behind current React that going to Preact is a very valid direction to take.
I also don't see why switching to Preact does not require updating, they even mention they will have to do this anyway, including some of their routing dependencies. Preact seems to be keen on keeping compatibility with React, referring to the current and previous versions, so it is very likely updates need to happen regardless.
Also, upgrading React is usually not too much effort as for most changes codemods are provided that do most of the work. Not saying it doesn't require effort at scale, but I don't see or read how Preact would make that any easier. Considering you'll use React libraries in Preact I would be worried about upgrading and compatibility later on.
I'm honestly interested as the lower bundle size is significant, but I'd like to know the other pros/cons and risks that surely are there.