8 ms·
> we’ve discovered that React also leads to some questionable practices. Like hovers in JS (rather than in CSS), drop-down menus in JS, not rendering hidden (un
by capableweb 6y ago
> we’ve discovered that React also leads to some questionable practices. Like hovers in JS (rather than in CSS), drop-down menus in JS, not rendering hidden (under a hover) text (Google won’t be happy), weird complex logic (since it’s possible!), etc.
This is some strange reasoning that I have yet to seen myself. If you can do the hovers states/drop down menus in CSS, why not do them in CSS, even if you're using React? Seems to be blaming something on a library that the library has no care about in the first place (which to be frank, seems relatively common in web dev circles).
> In the worst case, we would serve you 2.5MB of minified (non-gzipped) JS
And holy guacamoly, how do you end up with this?! Seems that something was surely wrong in the compilation options, forgetting to mangle names or something, missing dead-tree elimination maybe?
- swyx 6y agothey were using handrolled SSR in clojurescript, I'm not sure they set up code splitting.
- capableweb 6y ago> I'm not sure they set up code splitting Don't think that matters. I've written (from scratch and inherited) and deployed many ClojureScript frontends, from one page ones with lots of interactivity to 30+ pages/sections, none of them reaching the size of 2.5MB minified (when using the production settings for Closure Compiler). Add in SSR and/or code splitting and the weight should be nowhere near there, leading to the guess that something is wrong in their config or they are embedding binary files into the JS asset.
- piranha 6y agoOh yeah, binary assets. Yeah, it is certainly binary assets. We just embed node.js in there. /s
- deleted 6y ago[deleted]
- matsemann 6y agoWhen people are discussing one's article (I assume it's yours based on your profile) I know it's easy to go into defense. People may criticize, and that hurts. But before lashing out as you do in some comments here, consider that the readers don't have the same background and context as you, and we all discuss based on those. Throwing out React is a huge step for most projects, it may have been good for you, is probably not right for many, and is certainly a discussion worth having.
- piranha 6y ago> consider that the readers don't have the same background and context as you, and we all discuss based on those. Okay, so how about not inventing outrageous ideas on the spot and just consider what is written? It's equally as hard to unload what's been boiling in your brain for last half a year. I'm reading comments and trying to decide where to expand my post, of course, but this "binary" thing just got me laughing.
- juicypt 6y agoActually webpack has the url-loader which allows embedding binary data as base64 data URLs in your CSS bundle. If used judiciously it can even be a good thing too. EDIT: I mentioned webpack since the thread is about react, but you can do the same thing manually by putting the base64-encoded data in a data URL on a CSS file.
- capableweb 6y agoYou know, executables are not the only type of binaries, embedding a PNG file into the JS asset would also be considered embedding a binary asset. But I'm sure you knew this, you're just trying to be funny.
- piranha 6y ago:-) yeah, in the heat of the moment. There is of course things we could do to improve bundle size, but it's all components and logic. We didn't do any css-in-js or any other fancy stuff.
- hombre_fatal 6y agoThat first quote (using JS when CSS would be faster and simpler) does remind me of being a beginner and always arriving at jQuery's animate() for all my needs. That said, animation is hard, and React doesn't insulate you from that, so it takes some thought. In fact, being a layer of abstraction, it requires even more understanding of animation. Fading a component in is easy with regular CSS transitions. But fading a component out generically means that you have to keep the component mounted for the transition. Perhaps anyone who has used react-bootstrap's Transition system (animate={true} on modals and tooltips) has run into those quirks where you start seeing a pattern of animate={false} fixing all sorts of random bugs. With React, if you're grabby with 3rd-party libraries, you can end up with a russian doll of HoCs, each one from a different library, that are so generic that they kill performance and it's not even obvious why without being a profiler expert. Whereas without React, you wouldn't have found those solutions at all, so you roll your own cross-cutting solution. That isn't necessarily a problem with React, but something that you have to resist with frameworks in general. It reminds me of Ruby on Rails, googling "rails avatars" and ending up with two libraries like carrierwave + "has_avatar" when you could have just built your own simple solution. It's a form of technical debt. After all, it's hard to justify the effort of deabstraction when you're assigned to 100 other issues.
- Jestar342 6y agoRE: jQuery.animate() - that was around before CSS animations were. Animations were not in the CSS spec until v3 which only saw widespread support this side of 2010. Before then you could only do animations with Javascript, and frankly jQuery's `animate()` was a god-send.
- dsego 6y agoOn top of that, js animations are still better for controlling timing and events or for a more realistic natural motion (springs instead of timed easing).
- heavenlyblue 6y agoI would say that what JS animations are even better at is justifying inflated budgets of the projects made for people who are not very familiar with tech. Is there ever a real reason for animations that doesn't make the interface feel sluggish and unresponsive? In the other hand if you actually set the animation delay to something incredibly low, all of your animation needs could be easily solved by animating the transparency of the appearing elements.
- Etheryte 6y agoTalking of bundle sizes, this isn't inherent to the React point being made here but it's arguably too easy to blow up what you're serving. A common example I like to reference is Moment[1] — unpacked size is 4MB, most of which is different locales. If you _don't_ want to bundle all of those with your project, you have to do extra work, instead of making locales opt-in. Perhaps slightly less used, but a more prominent example, a widely-used table component Ag-grid[2] is 25MB before being packed down. Instead of being served as a modular set of components, it's mostly a big blob with minimal separation of concerns. The takeaway here is twofold: we need better tooling as well as better practices for how to use those tools. It's both an educational problem as well as a toolset issue. It is possible to build lean and fast pages, but it's currently considerably harder than building gargantuan monsters. I don't see the web bloat problem going away until the dynamic here is flipped — it should be easy to ship small bundles even with minimal experience. [1] https://www.npmjs.com/package/moment https://www.npmjs.com/package/moment [2] https://www.npmjs.com/package/ag-grid-community https://www.npmjs.com/package/ag-grid-community
- avasthe 6y agoTangentially related; is there no lint option (similar to use strict) in JS yet to ensure no methods / functions are dynamically called and thus allow effective dead code elimination?
- cellularmitosis 6y agoNot in vanilla JS. If you use the flavor of JS accepted by google’s closure compiler, then yes.
- avasthe 6y agoIf anything, it proves how ineffective standards committees are. Similar to the standard library proposal which seems to be not yet implemented. Still better than C++ standard people who try to cram infinite complexity into 100 layers of templates every three years for sake of adding a feature as library instead of language feature, with utter ignorance towards debug build performance, compile times and error messages. I have lost respect towards them since I read a C++ performance report and didn't see the mention of inherent STL inefficiencies.
- brainless 6y agoI have been with React for 4 years now. Link state can be driven through React if you are testing some state or URL (active URL). But hover should never be React driven. I can not fathom why anyone would do that.
- richthegeek 6y agoThe first legit reason I can think of is if you have a particularly complex UI with fixed/absolute/sticky positioning and you need tooltips. In this case, CSS gets in the way and you need to render the tooltip through a tooltip and so need to set the position using JS on hover.
- bryanrasmussen 6y agoLike in https://ant.design/components/tooltip/ https://ant.design/components/tooltip/? However, hover used.
- piranha 6y agoThe thing is that your tools should be making good this easier than bad things. And React is the opposite of that.
- tnova 6y agoSo youb are saying that React makes it easier to do bad things than good things? Would you mind extending on that?
- piranha 6y agoI tried to do that in the article. But the thing is that when you're writing a little piece of code React makes it dead easy to make hover in your code. There a lot of little things like that. You start out with good intentions, but after 4 years of different people certain parts of codebase start looking really weird even with code review. You just can't catch every little detail. And this is why tools should make it easier to do good thing (good as in what you'd want to see in the end).
- arexxbifs 6y ago> after 4 years of different people certain parts of codebase start looking really weird That's pretty much how software development works though. It's what happens when people with varying skill levels, schools of thought, preferences and approaches to problem solving all work in the same code base. Heck, it'll probably happen even if it's your own pet project: four years is a long time in something as fast-moving as web development, especially when you factor in things like market-driven priorities (E.G. adding new features vs. fixing old "good enough" crap kicking about). I honestly doubt there's a single software project in history that doesn't have shady corners after a couple of years, no matter how excellent their frameworks, conventions and developers are and how draconian their review process is.
- piranha 6y agoThat is true, but the effect various "quirks" have on result are very very different. I did not decide to switch from React with a light heart, it was a long and painful decision. But it seems to me that React's path of least resistance leads to a slow bundle, and you're going to fight an uphill battle.
- traveler01 6y ago> This is some strange reasoning that I have yet to seen myself. If you can do the hovers states/drop down menus in CSS, why not do them in CSS, even if you're using React? Seems to be blaming something on a library that the library has no care about in the first place (which to be frank, seems relatively common in web dev circles). Let's all be honest, that's complete laziness or lack of knowledge by the developer. > And holy guacamoly, how do you end up with this?! Seems that something was surely wrong in the compilation options, forgetting to mangle names or something, missing dead-tree elimination maybe? Maybe sourcemapping?
- ricardobeat 6y ago> Seems to be blaming something on a library that the library has no care about in the first place Libraries and frameworks establish idioms, which encourage or discourage certain patterns. In my experience React / JSX definitely encourage complexity and abstraction by making display and logic so intertwined, especially with hooks. > And holy guacamoly, how do you end up with this? Libraries upon libraries, one tiny problem at a time. Unless you're in a very small team, or have very strict policies for adding new dependencies and vetting their impact on bundle size, this will inevitably happen.
- madeofpalk 6y agoI cannot see how react encourages you to forget :hover in CSS.
- deleted 6y ago[deleted]
- dsego 6y agoIf a mouseover should trigger an an action that causes the component to redraw, those the hover state persist?
- ricardobeat 6y agoYou can argue it is not React's fault as usual, but this is how: <Button styles={[...]} onPress={() => setState('active')} /> const styles = StyleSheet.create({ active: { backgroundColor: 'purple' } }) progressing into: <Button styles={[...]} onPress={() => setState('active')} onHover={() => setState('hover')} /> const styles = StyleSheet.create({ active: { backgroundColor: 'purple' } hover: { backgroundColor: 'blue' } }) which is frictionless and 'clean', vs the alternative: const styles = StyleSheet.create({ button: { '&:hover': { backgroundColor: 'blue' } } }) The states here doesn't make a lot of sense, but I think it illustrates the idioms involved and how you end up focused on JS. This is so common I bet most devs who entered the market using React will see absolutely no issue in that. Another familiar case is not having direct control over a parent/child component's styles, only their state, making it impossible to do it with CSS. Not exposing `style` is very common in component libraries, and using CSS-in-JS means you can't easily target them with CSS selectors.
- Olreich 6y agoThe framework and libraries and information you find on the internet definitely encourages you to go for animations via JS. Might be a holdover from before CSS3, but I'm not sure I've ever seen people really try to use CSS3 for their animations unless people were working on their own toys. Just google "animated X react" and 80-90% of the articles are massive JS components with a little styling in the CSS. For size of the bundle, just remember the node_modules black hole meme. The amount and size of JS libraries is no joke, it's wildly out of control. 2.5MB minified non-gzipped is common mostly because of a paradigm of "once you gzip it it will be small, and inflating that doesn't cost anything, and this way everything is preloaded!". Libraries come with a bunch of images embedded as Base64 encoded strings, the full localization tables, 40 1kb depedencies (left pad and friends), etc. etc. etc. These are all the default and no one changes defaults. To make a reasonable web application today without all the insanity, you have to be very disciplined, because everything is pointing you toward doing dumb or crazy things.
- 1f60c 6y ago> dead-tree elimination The practice of removing unneeded code from a bundle using static analysis is commonly known as “tree-shaking”, but I like your version better. :D
- Izkata 6y agoLooks like "dead code elimination" is what this is generally called in compiler-land - another thing rediscovered in javascript-land and given its own name.
- coffeefirst 6y agoYeah, those are choices. You still have to understand what you're actually doing in the browser and the DOM, same as jquery or vanilla js. I can see how easy it would be to accidentally get a bonkers js bundle if you start using external dependencies without monitoring how much code they ship. Does React have a perf cost? Absolutely. But there's something else going on here.
- rmrfrmrf 6y ago> This is some strange reasoning that I have yet to seen myself. If you can do the hovers states/drop down menus in CSS, why not do them in CSS, even if you're using React? Because when requirements change and your hover animation needs some additional flare to it in certain cases, you'll be glad that you had automated unit tests to verify original behavior still works along with your customizations.
- phaedryx 6y agoWe were recently looking at https://ant.design/ https://ant.design/ which is one of the most popular React component frameworks. The components are nice and the design is appealing, but the 1.2 MB size is off-putting (https://bundlephobia.com/result?p=antd@4.5.3 https://bundlephobia.com/result?p=antd@4.5.3). "Wait," we told ourselves. "Surely, we can do some tree-shaking, replace momentjs, be strategic in our imports and shave a ton of that off" With all of that we got it down to 1/2 of the size, but that was still too big for our needs.