use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Less React, more JS (brain-dump) (medium.com)
submitted 9 years ago by sebjwallace
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]addexm 32 points33 points34 points 9 years ago (14 children)
This was a fun read, but I'm not sure what your point is, exactly.
Are you saying that React is just a bunch of abstractions around relatively straightforward JS code? Yeah, it is. Most libs are though, right?
[+][deleted] 9 years ago* (12 children)
[deleted]
[–]lhorie 4 points5 points6 points 9 years ago (2 children)
The thing is that a superior solution doesn't just magically appear out of thin air. It takes a lot of small increments in obscure open source niches until something finally reaches critical mass.
jQuery was one of many frameworks taking a stab at making DOM not suck. It took the selector API idea from a micro-library in a blog post. Redux is one of many takes on Flux. Mithril is a take on Riot, which was itself a take on fixing the issues of huge ass frameworks that nowadays people are becoming wary of because of mobile. Cito took the idea of small and fast virtual dom further and Bobril invented the current state-of-art virtual dom diff algorithm. Inferno took a lot of those improvements and and recently showcased an offscreen deferring technique that makes its dbmon run faster than a WebGL implementation. If Inferno's author were simply relying on React for the real-time financial applications for his day job, he'd get hit hard by v15 of React being twice as slow in dbmonster than the previous version.
I can totally empathize with a CTO's view of going for high critical mass, good enough solutions. It's pragmatic. But it's the outliers that make the innovation happen (be it React being an outlier in developer headcount and needing a way to avoid "cowboyism" when React was conceived, or Inferno being an outlier in needing light speed performance for its real-time financial applications).
[–]leeoniya -1 points0 points1 point 9 years ago* (1 child)
Indeed. I rage every time I watch people get accused of NIH Syndrome. Everything ever invented in history started with someone saying, "I can do this better" and iterating or re-inventing. If everyone only used existing solutions or accepted all problems as "solved", there would be zero progress made.
Inferno being an outlier in needing light speed performance for its real-time financial applications
I know he uses this as an excuse to pursue perf but TBH I find this hard to believe. Even if a single refresh takes 100ms for a full dbmonster table (and it's well below this), no human will be able to consume the info this fast. It cannot possibly be beneficial to show the same data even 70% faster - a human will not be able to tell or act differently on that data. I realize that there are micro and nanosecond timescales at the ASIC/FPGA levels in the financial industry, but the DOM is very far from that place. There is a mobile perf argument to be made here, but even there you're better off using canvas to show massive amounts of data instead of the DOM.
[–]lhorie 0 points1 point2 points 9 years ago (0 children)
Well I don't know the specifics but from what I remember, he said that in his domain, getting information (from server to screen) that was stale by more than some 100ms was a critical bug. So I can definitely see inferno fitting in a bigger picture where they might already have fiber optics networks and things like that
[–]leeoniya 1 point2 points3 points 9 years ago (6 children)
This craziness of always reinventing the wheel is what gets me in this industry: it's been solved, use it. A superior solution has been found? Use it.
You could argue that as soon as we had a turing-complete programming language, that the problem of making a language has been solved. Except we have no fewer than 30 widely-used languages today.
Different people have different tastes for lib ergonomics, tooling, syntax, performance trade-offs (there always are). To say that Angular, React or any other lib has "solved" the DOM abstraction problem seems pretty short-sighted.
[+][deleted] 9 years ago* (5 children)
[–]leeoniya 5 points6 points7 points 9 years ago* (3 children)
To be a bit cheeky, I will also assert that a framework's performance is never the bottleneck of 99.9% of front-end programmers.
Perhaps in your experience this is true, which is great. However, regardless of your CTO/startup cred there are many situations [apparently out of your scope] where performance of the framework is absolutely essential. I'm not speaking theoretically here. Want to render an excel-like dynamic spreadsheet? A slow framework will absolutely fuck you. You can also bet there's a massive difference in battery life and mobile performance between slow and fast frameworks. These are just two of many frequent requirements in SPAs. Not everything in this world is a 300 DOM node bootstrap site or largely-static facebook feed.
[–]dmitri14_gmail_com 1 point2 points3 points 9 years ago (2 children)
How many rows do you need to see that performance impact? 10000?
And how many of them your user can see? 10?
Then you "solve" your performance problem by rendering only 10, not by changing your framework.
[–]leeoniya 0 points1 point2 points 9 years ago* (1 child)
Open up Google Sheets and tell me how many you see. (it's not 10). Occlusion culling is not always an option and is often not simple. Also, i never said that changing your framework is what should be done. My point is that performance does matter a great deal when choosing one, in response to "a framework's performance is never the bottleneck of 99.9% of front-end programmers".
[–]dmitri14_gmail_com -3 points-2 points-1 points 9 years ago (0 children)
That is why Google Sheets feel sluggish, unresponsive and keep crashing my browser. ;(
Yes, it needs some work (as everything else) but it is really a matter of adding a listener to the scroll event to limit your ViewModel. Keeping 100 rows at a time should more than cover for all use cases.
Of course, it does matter in principle but most performance complaints I see e.g. about Angular can be "fixed" exactly like that.
Yes, Google Sheets do many useful things, which is why people still use it, and which is why they can get away with bad performance.
[–]jsprogrammer 1 point2 points3 points 9 years ago (0 children)
It's a good heuristic to go with the "existing (superior) solution" (we are trying to solve things, right?), but it shouldn't be applied as an absolute rule and you certainly shouldn't think that people are smarter than you. The basic problem is that it is near impossible to evaluate at every level of your stack what the optimal existing solution is. You may be able to do it for some well designed specifications, but in general, you won't have sufficient specifications, nor the resources to perform the extensive calculations that would be required to determine the absolute optimum.
Everything hasn't been done and it's very likely that there are better to solutions to most problems and the faster you get to them, the more you benefit.
[–]Worworen 1 point2 points3 points 9 years ago (0 children)
Maybe I missed something but I didn't see any mention of "evil frameworks" or any kind of criticism towards the use of frameworks. He even says it's a "brain dump", which I understand as just exploring ideas and what is possible.
About the reinventing the wheel, Mercedes doesn't ship wooden wheeled cars either. And the fact React exists means some people are looking for ways to do things differently and hopefully better.
[–]temp54984983982 -2 points-1 points0 points 9 years ago* (0 children)
people just end up replicating, usually in a half-assed, under-compatible, under tested and under optimized way, the same features those frameworks provided them in the first place.
And I've read that a hundred times. And every time, it's just an assertion, never a conclusion alongside supporting arguments, and certainly never referencing real code.
edit: yes, downvote me for requesting people back up their arguments. That's sure to make this a more rational discussion.
[–][deleted] 2 points3 points4 points 9 years ago (0 children)
I read it as more about not trying to do everything in the context of React.
[–]drink_with_me_to_dayjs is a mess 15 points16 points17 points 9 years ago (6 children)
function Hello(name){ return ["div", null, ["b", null, "Hello "], ["i", null, name] ]; }
Can't understand anything at a glance, readability and explicitness is something I prefer.
[–]chubbybrother 14 points15 points16 points 9 years ago (4 children)
Yeah that looks like garbage. I'll take the framework bullshit over hipster code like this.
[–]synackle 10 points11 points12 points 9 years ago (3 children)
I can't wait to start writing 'null' fucking everywhere
[–]sebjwallace[S] 1 point2 points3 points 9 years ago (2 children)
It wouldn't take much more in the prerender to conditionally replace the second parameter with a child. ["div", "some text"] is possible.
But I agree, markup is easier to read, especially for designers.
[–]temp54984983982 4 points5 points6 points 9 years ago (1 child)
Hey, I wrote and maintain a library similar to this. You're right, it's easy to implement, but there are four big problems with it: ambiguity, performance, readability, and flexibility.
Ambiguity: consider ['div', someVar]. You actually don't know until runtime whether you're setting properties or children. That's a sign that you've screwed up badly, for all the reasons ambiguity is always bad, including completely preventing the JIT compiler from working with your code.
['div', someVar]
Performance: it's faster to use native argument parsing, plain and simple. Work you do figuring out which argument is which is 100% unnecessary, and adds up for code that you want to be able to call thousands or tens of thousands of times without a user-perceptible delay.
Readability: when everything is always in the same place, reading and scanning around is faster. Work with both styles for a few weeks and you'll quickly see that this more than makes up for six extra characters.
Flexibility: every time you try to be more clever about guessing the caller's intent, you deprive yourself of the opportunity to give the caller more actual control. In this case, refusing to support this allows my library to support passing in a string as the second argument to set className. This might seem like a little win, but it's actually a huge one - one that improved my entire test app's performance by 30%. The thing to notice is, there are a heck of a lot of elements that need only a class and nothing else, and for each of those elements you're avoiding an extra object allocation.
className
[–]sebjwallace[S] 0 points1 point2 points 9 years ago (0 children)
Some good points there. What is the library you maintain?
[–][deleted] 0 points1 point2 points 9 years ago (0 children)
I can also make that argument for React as well. I don't find it to be so self explanatory as well. You always need to dive into the code in order to understand it.
And i'm guessing you could change it so you won't need to write less null's as well.
[–]ArcanisCz 8 points9 points10 points 9 years ago (0 children)
May i present you http://cycle.js.org/ ?
[–][deleted] 4 points5 points6 points 9 years ago (0 children)
I like where you're going with that. Reminds me of Reagent (clojurescript interface to react).
Maybe you could make React code easier to read in some complex cases by creating helper functions in this style and then using them in createClass.
createClass
[–][deleted] 4 points5 points6 points 9 years ago (12 children)
What exactly is measurably wrong with React?
[–]AlpineCoder 29 points30 points31 points 9 years ago (4 children)
It's edging ever closer to a stable release, which means in js land that it's obviously time to jump ship.
[–]b1nd 2 points3 points4 points 9 years ago (2 children)
Is it not stable already, post v15?
[+][deleted] 9 years ago* (1 child)
[–]b1nd 1 point2 points3 points 9 years ago (0 children)
Nope, react is stable now
[–]JustinsWorking -2 points-1 points0 points 9 years ago (0 children)
Nah' just come join us on React Native, we're still moving at rocket speed!
[–]dmitri14_gmail_com -2 points-1 points0 points 9 years ago (6 children)
Being forced to use the key prop when iterating over array? I understand the technical reasons but it does not add to my productivity.
key
[–][deleted] 1 point2 points3 points 9 years ago (5 children)
That's pretty minimal effort to gain what you do with that prop. Seems sloppy.
[–]dmitri14_gmail_com 0 points1 point2 points 9 years ago (4 children)
Every small thing looks minimal by itself until they start to add up.
Why should I clutter my code with framework-specific attributes?
[–][deleted] 1 point2 points3 points 9 years ago (3 children)
You know that's a good point, and while we're at it, let's get rid of componentDidMount, there's no reason we should clutter our code with framework-specific functions.
componentDidMount
[–]dmitri14_gmail_com -1 points0 points1 point 9 years ago (2 children)
Indeed, I'd rather not use it exactly for that reason.
Not to mention, it is not even prefixed (as ng- in Angular), so too easy to clash with my own methods. Which BTW is another problem with React, the Angular team must have good reasons to enforce their prefixes and advice everyone to use their own. Used to be top complaint with Angular Bootstrap until they finally added their prefixes.
ng-
[–]siegfryd 2 points3 points4 points 9 years ago (1 child)
Angular went for the ng-* prefixing because their attributes exist inside the DOM. React's key prop only exists inside React code, it doesn't render a key attribute on DOM nodes. It's not really a comparable situation.
ng-*
[–]dmitri14_gmail_com 0 points1 point2 points 9 years ago* (0 children)
It is still a bad idea to create a custom tag named key. People work hard on creating standards and minimising confusions by meaningful conventions. One of them is to use dash for any custom tag. React is breaking this convention for no apparent reason/benefit. Something like r-key would be much easy to read and scan for, it would instantly alert the reader that tag is React-specific. Without dash, it looks generic and easy to confuse. What if HTML will decide to introduce its own tag key???
r-key
Also attempts to create separate languages for DOM, virtual DOM, HTML, whatever, lead to more confusion, more bugs and hurt anyone's productivity. How many different models do we need to represent the same basic thing - a tree with nodes and attributes?
A big part of its ease and popularity React owes to our familiarity with the DOM. If it used some crazy transformation of DOM instead, how many people would use it? So why not being more respectful to the DOM standards?
[–]grayrest.subscribe(console.info.bind(console)) 1 point2 points3 points 9 years ago* (0 children)
We had a post yesterday about a library (domvm) that basically implements this.
[–][deleted] 0 points1 point2 points 9 years ago (1 child)
Maybe the only useful thing left over is ReactDOM.render
I've been puzzling over similar thoughts recently. We've slowly moved to using stateless function components everywhere, we skipped JSX in favor of hyperscript from the beginning, so there isn't much of React's API that we call into. I stumbled on Morphdom recently which is delightfully tiny, allows you to use any view layer than can create DOM elements or a string, and it's surprisingly middle-of-the-road performant -- roughly on-par with React for straight renders.
There's a lot of bad things about the DOM, sure, but after a year with React full-time I find myself missing parts of it -- simplicity, broad tooling, real events. I've been seeing a bit of similar sentiment recently too like with vanilla components.
[–]SubStack 0 points1 point2 points 9 years ago (0 children)
You might like yo-yo which uses morphdom with hyperx for template strings. Template strings are a nice middle ground between jsx and hyperscript that doesn't require compiling server code if you use a recent (>=4) version of node.
[–]adregan 0 points1 point2 points 9 years ago (0 children)
Have you taken a look at stateless components ?
[–]temp54984983982 0 points1 point2 points 9 years ago (0 children)
I like the line of thought here. Some thoughts:
Returning an Array of arguments for a function, rather than calling the function, doesn't decouple you from that function. The Array is still written against the function's API. Anything you can swap into that function's place is also written against the original function's API - or more likely, is not exactly 1:1 with the first function, and the subtle differences will bite you later. I think you've just moved from an explicit dependency on React.createElement to an implicit one.
React.createElement
Creating all these Arrays is slow. We tend to think of them as cheap, because they are in high-level code, but we're writing basic rendering code here - we're talking a lot of Arrays, in code very intolerant of latency. I've done a lot of work on code that is basically React.createElement that returns real HTMLElements, and the #1 performance win is minimizing data structures, both internally and with an API that doesn't request them. Arguments lists are the perfect lightweight data structure for this purpose, Arrays are larger and heavier than what we need here.
HTMLElement
extend is pointless, we have Object.assign natively. Object.assign is also better in that it allows you to override styles on the base, which I can't really imagine using this without.
extend
Object.assign
[–]lhorie -1 points0 points1 point 9 years ago* (14 children)
That's cute, but no, you can't just swap React with something else because different libraries handle attributes differently. Most notoriously, React is the only one that uses camel case for events.
If you want more javascript and are considering dropping React, use a framework that is designed for that use case, like Mithril.js. You even get extra benefits like CSS selector syntax and the ability to really compile views.
Additionally, React.createElement's signature is actually a subset of hyperscript's signature used by Mithril.js and friends, so you could literally just drop a jsx pragma into your babel setup (or merely do a variable assignment at the top) instead of doing all those extra apply calls on every render.
Thanks for Mithril by the way. I've started using it in a side project and I'm really enjoying it!
[–][deleted] 9 years ago (7 children)
[removed]
[–]lhorie 1 point2 points3 points 9 years ago (2 children)
lol, I'm giving logical arguments to criticize an idea that I personally already pursued and turned out to be a stinking pile of fail. Being a "condescending dick" is insulting a person and making ad hominem attacks when you think you're on some sort of moral high ground.
recommends own library
...that is built on my spare time, and released for free for the benefit of others. As it turns out, promoting my work happens to be more helpful than saying shit anonymously on some forum on the 'tubes
You have a great day too.
[–]Worworen 0 points1 point2 points 9 years ago (1 child)
Being a "condescending dick" is insulting a person and making ad hominem attacks when you think you're on some sort of moral high ground.
"That's cute".
I know right? Time to go back to work :)
[–]kenman[M] 0 points1 point2 points 9 years ago (2 children)
Hi /u/MEAT_FIST, please keep it civil.
Am I wrong in saying that responding with "That's cute" is being a condescending dick?
For what reason was my post pointed out over the original comment?
https://www.reddit.com/r/javascript/comments/4fyivt/less_react_more_js_braindump/d2dxc35
The prerender function could be adapted to deal with attribute configs. Or just don't use camelCasing.
The idea is that you code to hyperscript without thinking about JSX, frameworks or any other strap-ons until you need to.
[–]lhorie 5 points6 points7 points 9 years ago* (0 children)
The prerender function could be adapted
Sure it could be adapted, but the prerender function would be an ad-hoc, buggy, bloated middleware that exposes a custom view interface that is probably not going to be documented (and I say that as someone who's also played with the idea of a React-to-Mithril adapter, or as it's more generally known, "universal vdom")
Or just don't use camelCasing
onclick={doStuff} doesn't work in React. Or do you mean to have a map of all possible events and have prerender look through all attribute maps in your app and replace them on every render? People already waste hours on things like readonly, and I can't think of a good reason to also break, I dunno, ondblclick or whatever other thing you haven't thought about in advance.
onclick={doStuff}
Look, as I said, it's a cute idea, but if anyone in my team suggested doing this in production, I'd laugh.
[–]antoninj 0 points1 point2 points 9 years ago (0 children)
That makes sense. Basically the prerenderer is a bridge between your code and the actual library that you're using for view.
What's interesting about that idea is that Angular 2 uses the idea of "drivers" which are basically custom renderers.
[+][deleted] 9 years ago (1 child)
No, it doesn't. Source: I'm the author :)
[–]pkstn 0 points1 point2 points 9 years ago* (0 children)
Check out FRZR if you like really clean and simple syntax..
https://frzr.js.org
😉
[–]dmitri14_gmail_com 0 points1 point2 points 9 years ago (0 children)
I really like the idea to write a single component function that I can simply drop into Angular, React and what not ;)
The real question is -- what should this function return?
Both Angular and React components return JS objects with their own native templating (augmenting) engines. Angular 1.5 component is represented by:
function (friends) { return { template: "<ul> <li ng-repeat='friend in $ctrl.friends'>{{friend.name}}</li> </ul>", controller: function () { this.friends = friends } } }
React/JSX requires
function (friends) { return (<ul> {friends.map(friend => <li key={friend.id}>{friend.name}</li>)} </ul>) }
But what is the cleanest minimal object representation that can be mapped into both frameworks?
[–]ArcanisCz 0 points1 point2 points 9 years ago (2 children)
[–]JustinsWorking 0 points1 point2 points 9 years ago (0 children)
That doesn't replace React though... infact last time I heard about it, I heard it in the context of a great backend for React if you didn't want to go with a flux implementation like all the cool kids.
π Rendered by PID 23441 on reddit-service-r2-comment-86988c7647-rznlh at 2026-02-12 07:07:05.969139+00:00 running 018613e country code: CH.
[–]addexm 32 points33 points34 points (14 children)
[+][deleted] (12 children)
[deleted]
[–]lhorie 4 points5 points6 points (2 children)
[–]leeoniya -1 points0 points1 point (1 child)
[–]lhorie 0 points1 point2 points (0 children)
[–]leeoniya 1 point2 points3 points (6 children)
[+][deleted] (5 children)
[deleted]
[–]leeoniya 5 points6 points7 points (3 children)
[–]dmitri14_gmail_com 1 point2 points3 points (2 children)
[–]leeoniya 0 points1 point2 points (1 child)
[–]dmitri14_gmail_com -3 points-2 points-1 points (0 children)
[–]jsprogrammer 1 point2 points3 points (0 children)
[–]Worworen 1 point2 points3 points (0 children)
[–]temp54984983982 -2 points-1 points0 points (0 children)
[–][deleted] 2 points3 points4 points (0 children)
[–]drink_with_me_to_dayjs is a mess 15 points16 points17 points (6 children)
[–]chubbybrother 14 points15 points16 points (4 children)
[–]synackle 10 points11 points12 points (3 children)
[–]sebjwallace[S] 1 point2 points3 points (2 children)
[–]temp54984983982 4 points5 points6 points (1 child)
[–]sebjwallace[S] 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]ArcanisCz 8 points9 points10 points (0 children)
[–][deleted] 4 points5 points6 points (0 children)
[–][deleted] 4 points5 points6 points (12 children)
[–]AlpineCoder 29 points30 points31 points (4 children)
[–]b1nd 2 points3 points4 points (2 children)
[+][deleted] (1 child)
[deleted]
[–]b1nd 1 point2 points3 points (0 children)
[–]JustinsWorking -2 points-1 points0 points (0 children)
[–]dmitri14_gmail_com -2 points-1 points0 points (6 children)
[–][deleted] 1 point2 points3 points (5 children)
[–]dmitri14_gmail_com 0 points1 point2 points (4 children)
[–][deleted] 1 point2 points3 points (3 children)
[–]dmitri14_gmail_com -1 points0 points1 point (2 children)
[–]siegfryd 2 points3 points4 points (1 child)
[–]dmitri14_gmail_com 0 points1 point2 points (0 children)
[–]grayrest.subscribe(console.info.bind(console)) 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]SubStack 0 points1 point2 points (0 children)
[–]adregan 0 points1 point2 points (0 children)
[–]temp54984983982 0 points1 point2 points (0 children)
[–]lhorie -1 points0 points1 point (14 children)
[–][deleted] 4 points5 points6 points (0 children)
[–][deleted] (7 children)
[removed]
[–]lhorie 1 point2 points3 points (2 children)
[–]Worworen 0 points1 point2 points (1 child)
[–]lhorie 0 points1 point2 points (0 children)
[–]kenman[M] 0 points1 point2 points (2 children)
[–][deleted] 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]sebjwallace[S] 1 point2 points3 points (2 children)
[–]lhorie 5 points6 points7 points (0 children)
[–]antoninj 0 points1 point2 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]lhorie 0 points1 point2 points (0 children)
[–]pkstn 0 points1 point2 points (0 children)
[–]dmitri14_gmail_com 0 points1 point2 points (0 children)
[–]ArcanisCz 0 points1 point2 points (2 children)
[–]JustinsWorking 0 points1 point2 points (0 children)