One of the biggest reasons I favor React is that it's much easier to add a templating language to a programming language (i.e. JSX) than the other way around. Every construct for making decisions based on your data, traversing your data, etc. is more cumbersome and harder to validate in handlebars or whatever identical looking templating language the community came up with this week.
I also am strongly against string references to model properties in your template. Again, it's much better to use tools that provide some static validation of what you're doing.
Give me React with TypeScript to help me make sure I'm passing around what I said I'm expecting to receive at each point as features are changed and added, and I'll be in business.
Honestly, I use React in spite of my opinion of Facebook.
JSX frustrates me. When did we suddenly start thinking <> syntax was desirable again? When did the complexity of combining markup syntax and a programming language become a good idea? Why are we forcing this crazy complexity into every language and every IDE / code editor out there?
I much prefer react with standard functions e.g.
var element = DOM.p({id : "thing"}, DOM.div(), DOM.div());
You can use an API like this in every language without any hacks. It doesn't hurt readability or productivity and it has normal expression evaluation semantics. JSX isn't syntactic sugar, its a gross "syntactic artificial flavour" because it doesn't make the syntax easier, it just makes it look something a bit like HTML but with dozens of subtle differences e.g. attribute names, attributes values, tag closing rules, special extensions etc.
Frankly, yes it does hurt readability. I used to have your mindset and you're making the assumption that what looks okay when creating one single element will look fine when nesting dozens (which react excels at).
JSX is well defined and does not support any of HTML's looseness. It's predictable. It makes the code easier to follow. And if you don't want to use it, you don't have to. I see no issue.
You may prefer one or the other but most would admit they are pretty similar its just that the former hasn't needed an entire new language inlined into it. Given JSX has all its angle brackets, end tags and escaping expressions with {}, it can actually be more verbose.
I'm a C# guy and even I would say the JSX is far more readable there. I'm sure there's a law somewhere that says the less abstraction the better, that can be applied in this case.
I don't mind if people prefer JSX its just a shocking cost - rewriting language ASTs, build tools and IDEs for something that rhymes with html but is really only a couple of characters away from standard language constructs.
> I'm sure there's a law somewhere that says the less abstraction the better, that can be applied in this case
JSX is literally an extra level of abstraction. You are not writing html but calling a function to create a data structure element and JSX totally obfuscates that. I pity poor programming newbies trying to understand what JSX is actually doing "so you are telling me <div> is a function...but?".
In the functional form its just your normal language, nothing is disguised, everyone can see what it is doing and no post-processing magic is required e.g.
public class DOM
{
public static IElement div(object attributes, params IElement[] children)
{
return new Element(...);
}
}
I agree with everything you say, except the "shocking cost" part. Its all a matter of perspective.
You would have to write the transpiler anyway, since on a larger team if you're working with a designer, you would probably get HTML from them and soon get tired of manually translating it to function calls.
I'd bet this is how JSX got started in the first place.
In my experience, using a programming syntax for markup actually turns into a PITA. My only experience is HTML + Silverlight, but in both instances doing it in markup over code is almost always easier/quicker/simpler to read/less TLOC.
I agree that I wouldn't change your current tooling, as the cost isn't worth it. JSX isn't that great. But even though it turns that HTML into function calls, there is still an expectation of how it will work: i.e. those functions will still produce the specified html. At the end of the day, writing a layout in html is so much more intuitive than using function calls. Makes me think of how MS introduced the XAML language when they created WPF, making it far nicer to build UIs out of code than in winforms.
I will never understand why people think JSX style processing is a good idea. It's hiding what's actually happening, at no benefit (or very little benefit). At least with the former (C#) I can neatly build things up, reuse those components, instead of passing some monstrosity around.
I don't understand this. You could build up the template using jsx exactly like you could otherwise. For instance, I could put that in a variable and then use it in another template via {}
You could, but it's unintuitive (in my opinion) to do so -- which was the parent's comment larger point. You're not doing anything different, and to an extent the latter is actually lying about what's going on (you're not writing HTML). I also lose a certain level of tooling by doing it the JSX way. Why try to mask what you're doing? Why make it harder for your tools to help you out?
I guess I haven't felt this pain that you've felt. I'm satisfied with my tooling and feel that small components help keep things very clear and focused.
The time I spent fixing logic and layout bugs on several build-a-dom projects has taught me this. For the same reason using CSS Selectors to crawl the DOM is superior. When it doesn't work, how hard is it to spot the bug? If you're working on the front end you need to look things up roughly the same way for style and behavior, and emit them roughly the way the browser will see them when it's time to look them up.
And yet I'm still in the anti JSX camp. I think it has something to do the gear switching that comes with opening up the mixing of data and logic but I can't articulate it farther than that,
Your brain can only juggle a handful of bits of data at a time. If you see someone doing something that looks like this doesn't apply to them, it's most likely because they've memorized the code. And to memorize code, that means it can't change much or very often. Which makes them dangerous. They have a bias toward maintaining the status quo, no matter how awful it is. Don't be that person.
Many people find deeply nested tree structures hard to read when you need to mentally balance a bunch of parentheses. The inability for s-expression languages to gain significant traction with lay programmers is evidence of this.
People who use Lispy languages do _not_ balance parenthesis mentally. In fact they completely ignore parenthesis and go only by indentation. Parenthesis disappear when you are at certain level of proficiency.
Yeah hiccup syntax is my favorite as well. JSX is mentally the same thing for me except I read "HTML" faster than data structures if that makes sense.
I wonder if Hiccup was the first one to introduce this syntax? I never bothered to check but I always thought the JSX inventors might have been inspired by it.
I somewhat agree, but a little inconvenience comes when you have to insert HTML that you got from somebody else, like from a design template or an ad or analytics code. Sure you can convert it by hand or with an editor extension but then you are just doing the same as JSX, or you can insert it as a string but then it becomes inconsistent.
If JSX is embedded in a codebase, what is the value of that? Let me clarify a bit. What is the value in creating a limited tool optimized for neophytes that will be used extensively by experienced professionals, who would be better served by flexibility?
I had a lot of success back in 2013/14 by having our outsourced graphic designer directly modify JSX files in our codebase. He picked up just enough javascript to figure it out. I just told him where the file was or set up a test harness and he delivered pull requests against our actual codebase.
I think you are being a bit overdramatic about JSX. There was zero learning curve -- except for a few errors initially when using class instead of className...
The argument that DOM.div() is more readable than <div/> is honestly hilarious to me. Any non-trivial tag structure will be unnecessarily complicated through the API. Especially when you can just write it almost exactly how it's going to look when it becomes HTML in JSX.
DOM.div() vs <div/> seems like a bad example. IMHO, when you get an element with tons of event handlers and conditional classes, or when you have a deep chain of ternaries that's where angled bracket syntax starts to become unwieldy.
The className thing is a big deal too, in my opinion. Preact and Mithril do what you would expect, and perf doesn't suffer, so why can't React/JSX normalize it as well?
If you have deep chains of ternarys, that's a symptom that you should be splitting your rendering code into another function or component. This would be true regardless or what approach you are taking to templatihg.
That's one thing I really appreciate about jsx: the lack of rich template code syntax makes it glaringly obvious when your template code is doing too much and should be refactored. It does a really good job of keeping your logic in javascript and out of your template.
Refactoring into functions/components doesn't magically make a complex ternary tree go away. It helps the body of each branch be less noisy but the ternary tree will still be there.
You're talking about taking something like `foo && bar || baz && quux` and turning it into `isSomeCondition()`, but that's a pretty obvious refactor in any templating system.
At this point, I think it's perfectly valid to have the opinion that JSX isn't helping much, since the JS-to-HTML ratio in this case is relatively high.
Refactoring would just make it more difficult to mentally piece things back together given you would end up with sparse component instantiations scattered amidst otherwise-procedural js code, as opposed to the more ideal single-root, declarative virtual dom tree.
Without understanding what x.type is, I'd be inclined to write that without any ternary operator at all using plain old if statements with each returning JSX markup. I try to keep logic in JSX to simple ternary operators and loops at most. JSX is really just shorthand for DOM.div() for me. I imagine the code structure looks pretty similar to actually using DOM.div though. I'm not seeing how programmatically creating markup with DOM.div results in significantly different code, although if you have some good examples I'd love to understand them better.
Pulling things out into plain if statements is fine if you only have one or two, but in my opinion, it gets progressively harder to understand the code as the number of if statements increase (for the same reason that writing vanilla DOM creation code does). In my experience, when this type of refactor is allowed, it's common to pull just about everything up to the top of the render function (conditional className compositions, conditional components, even loops). This increases cognitive load because now the maintainer has to mentally piece everything back together on every read. Having been that maintainer, I'd say it's the sort of code that it's fun to write, but not fun to read.
The rationales in favor of hyperscript are largely cosmetic (e.g. JS indents more naturally), and I think that's very much a potato-potahto kind of discussion. Personally, I feel that hyperscript is more readable (because of the terser CSS selector syntax), but likewise, I totally understand that some people find angled brackets easier to read even if that entails super long attribute lists.
Ternary operators should never be nested, whether you're using JSX or not. If you have that many conditionals you should use variables and/or decompose the optional pieces into sub-components. Pretty much any time you have a tag that has a huge number of attributes, it's a smell that you need to decompose something.
Variable assignment is the simplest answer, which takes advantage of the fact that null or undefined values are ignored in JSX:
const Dashboard = (props) => {
let avatar;
if (props.user) avatar = <Avatar user={props.user} />;
return (
<div>
{avatar}
...some other content...
</div>
);
};
Regarding class vs. className: class is a reserved word in JS. It's not really a perf thing, it's the fact that JSX was intended as a very simple transform. If JSX used class instead of className, the transpiler would need to be contextual since "class" would sometimes mean "css class" and sometimes "JavaScript class". The baseline complexity for the parser would be higher and could lead to all sorts of complexity. Rather than deal with that the React team avoided the problem by using className instead, keeping things simple.
I think this proves lhorie's point. Markup syntax is dominated by code when you are building complex dynamic apps instead of static documents. What do you really gain by putting angle brackets around Avatar instead of calling a function?
FWIW I believe new react devs are slow to realise they can use local variables like this because JSX looks like it is doing string templating instead of object instantiation.
The example I gave was simplistic, but the value of JSX is the ability to easily nest elements. For instance, let's take my previous example and say we're creating a profile link:
const Dashboard = (props) => {
const {user} = props;
let link;
if (user) {
link = (
<a href="...">
<Avatar user={user} />
<span>{user.name}</span>
</a>
);
}
return (
<div>
{link}
...some other content...
</div>
);
};
If you want, you could create a `createProfileLink()` function, or you could create a `ProfileLink` component, or you could keep it as a variable in the `render()` function. This flexibility is what makes JSX powerful.
> but the value of JSX is the ability to easily nest elements
There is nothing there that "makes JSX so powerful", its just hiding function calls and varargs. Its only xml-ish syntax. You are welcome to prefer it but its not adding anything functional beyond that.
const Dashboard = (props) => {
const {user} = props;
let link;
if (user) {
link =
DOM.a({href: "..."},
Components.Avatar(user),
DOM.span(user.name));
}
return
DOM.div(link, ...some other content);
};
Yes, I understand how JSX works. My point is that it permits nesting in a syntax that is much simpler and emulates markup, which is familiar to web developers.
It's okay if you prefer to write code using the direct function calls, but I'm not sure most people would agree with you. I've built a product using direct calls (in CoffeeScript) and using JSX, and JSX was far easier to work with and less error-prone. YMMV.
I disagree in two ways: the first is that the ability to write template composition procedurally isn't specific to JSX. You can do that in plain js/hyperscript just as well.
The second point is precisely that this is procedural code. If the ability of putting together templates procedurally is the pinnacle of templating power/expressiveness, we might as well go back to Backbone.js.
> Regarding class vs. className: class is a reserved word
> in JS. It's not really a perf thing, it's the fact that
> JSX was intended as a very simple transform. If JSX used
> class instead of className, the transpiler would need to
> be contextual since "class" would sometimes mean "css
> class" and sometimes "JavaScript class".
I don't think React should have used `class` instead of `className`, but this isn't the reason.
<foo className="bar" />
compiles to
React.createElement("foo", { className: "bar" });
It could have just as easily have been that
<foo class="bar" />
compiles to
React.createElement("foo", { 'class': "bar" });
as far as JSX is concerned (or even without the quotes in an ES5 world).
The output isn't the problem; it's that "class" is also a keyword in the JSX input. I admit, though, I'm not intimately familiar with the JSX transpiler and am just guessing as to their motives.
I'm actually fine w/ JSX being "dumb" and just translating `class` to `class`, but when used in conjunction w/ React, the end result is that the JSX "markup" has a lot of traps that simply don't exist in similar libraries like Mithril.
`className` isn't the only offender. `onClick` and `readOnly` are other notorious one. And then there's stuff like `xlinkHref`, because it's not like anyone ever imports SVG from external tools.
className was named that to avoid conflict with the JS class syntax originally I believe, since JSX is inline - they probably could put in the work to change it at this point, but it seems like a minimally beneficial change but massively disruptive at this point.
There's also stuff like onClick, readOnly, xlinkHref... I would guess that a healthy number of React-related google searches are related to these gotchas
Haven't had the chance to try it myself but I have read quite a bit and I like what I see, particularly the high quality error messages in the compiler. However, I think I'd have a hard time getting my team on board with it as we use Visual Studio for the bulk of our development, and we would need to learn to work with the JavaScript interop APIs to do things like try Elm out for a single new feature on a page.
I've personally been impressed with learning Mithril over React. Surprisingly easy to learn for people coming from React and super fast. XHR and routing are included. You can use JSX but hyperscript (pure JS that has no compilation step) is favored for markup. Add in some Aphrodite for inline styling your components, Redux for state management and you have a pretty robust, blazing fast framework that is sufficient for many modern application without all the package bloat.
The HTML snippet embedded in `let titleView = "<h1>Hello</h1>"` can only be parsed as a string. This means no tooling support - no linting, no tags that autoclose, no code formatting. But if you have a distinct syntax for XML, the parser can clearly figure out what the strings are, and what the tags are.
First class support for XML is, after using JSX, just so obvious in hindsight if you're building anything to do with the web.
Scala introduced first-class support for XML through a DSL a decade ago. I believe the feature has been phased out because it was useless. I've personally never found it useful either.
When a react component tree has more than 3 level height, react component's lifecycle callbacks start getting crazy unmanageable.
Mounting, unmounting, rendering, props receiving, updating etc, these callbacks' calling orders open to bad rendering practice(e.g. unnecessary render, unexpected calls), that's why people avoid putting logics in there. It claims to be self-contained but parent-child communication breaks it in several ways, I am not a big fan of HOC.
People claim the simple of "just a view layer" of react, I don't think so. I haven't tried vuejs, but it seems like it takes care of most rendering callbacks/component communication seamlessly.
> It claims to be self-contained but parent-child communication breaks it in several ways
I think you'll find that most react developers advise against doing parent-child communication in react components for all but the simplest cases. Does it involve writing higher order components? Probably. Curious, why aren't you a big fan of them?
Higher order components to me is a hacky technique and mostly seen as a monkey patch to the limitation of lower component.
A concrete example is responsive table components with the help of HOC, says `react-dimensions` (sorry author, I have to mention here but there is nothing specifically wrong with it), why do I need it as a separate component? Oh flexibility and reusability but when I tried wrapping 2 or 3 table libraries with it, it sucks at rendering on desktop, even worse on mobile! I gave up on performance issue. Ah that doesn't mean the HOC technique itself is bad, but from my experience it is.
I know what you mean with regard to event handlers being passed down to children and children of children and so on and the complexity that can bring. I haven't used redux, but I understand it as being an attempt to simplify that kind of problem.
I haven't written any higher order components myself, unless you consider parameterizing event handlers in props to be higher order.
Composing pure functions makes more sense, passing function as argument in functional languages is way better than having the higher order component thing. Sure javascript can do that but in the react world, "component" thing go with you everywhere regardless of presentation or dumbest components.
There is the choice of preact[1], that has a very similar api, is more lightweight and even has a compatibility layer for the few react packages that need it.
Why would you? React is a tool. The fact that FB doesn't use the tool correctly shouldn't reflect negatively on the tool. That "honor" goes to the product.
Generate the markup on the server and send it down to the client! It's post-modern web development. Back to black.
You don't need 100 KB of code to spit down a table of data or show someone a directory listing of their github project. You don't even need an SPA, bunny.
And for goodness sake, when you do need to do anything in javascript, you can use document.createElement and document.createDocumentFragment. These are perfect 1:1 browser APIs that allow you to do everything you've ever wanted, there's no magic, they call directly into the browser engine to give you what you need.
If you want to increase performance, start first by measuring everything. Time to first byte. Time to DOMContentLoaded. The page onload event. window.performance timings; do real user monitoring, not TODO app benchmarks on the latest framework flavor of the week.
The entire web community needs a healthy dose of pragmatism. But it's okay, it gives me extra work. I really enjoy doing freelance performance work and telling everyone which code/library/framework is to blame for performance issues and rewriting everything so simply. Show people what works and you'll find they shut up real quick.
Every tool for its job. If you have serious dynamic behavior and you try to handroll it yourself, you risk either low maintainability and bugs in your bespoken optimized DOM manipulation algorithm or doing things in fundamentally inefficient ways. That said, people should be cautious about taking on new dependencies, and definitely need to take an evidence-based approach to performance optimization.
> Agreed, but currently there is no great solution that allows you to do that and provide the kind of UI dynamism that really does improve UX.
Strongly disagree that there's any actual improvement on UX. Plenty of sites like GitLab, GitHub, YouTube, etc. insist on using JS to load what could be entirely separate pages, but instead leave the user with some slow, hand-rolled progress bar on the top of the page. For sites doing nearly-full-page refreshes, a server pre-rendering is going to be faster. For sites doing smaller content-level changes, there's no reason something like turbolinks, pjax, or regular old ajax/DOM manipulation can't be used, which is almost always faster.
That value is set both on page load, and also (justifiably, IMO) dynamically. Multiply that by a hundred bespoke things and you yearn for less server client spaghetti.
Furthermore, and pardon me if this is stating the obvious, but improving the underlying technology for UX does not necessarily lead to an actual improved UX. Look around. There continues to plenty of misused (?) technology (i.e., crappy user experiences.)
In short, technology isn't the problem with most UXs.
Vue 2.0 claims server side rendering support, so you should be covered on initial page load. After that it's progressive enhancement.
For complex pages, AJAX is going to pay off in the long run. It's a matter of whether you can avoid having to implement and debug your entire app 2-3 times in order to get that behavior. That's the (mostly undelivered) promise of Node.
But at this rate web assembly may server code written in more robust languages to find its way into the client and take market share. As someone who grew up on the advantages of static code analysis, I look forward to getting some of that power back.
I really think for most cases you only need a view library instead of a heavy application framework. There are only a few cases there something as heavy as Angular or Ember is justified and in many scenarios a thinner view layer like Vue, React, Inferno etc is much better suited. Most of the web is simple enough to not need fancy http features or complex routing support. Everyone rushed to Angular without considering if they needed such a heavy library. How Angular even runs on mobile is anyone's guess.
IMO this is not true at all. Any non-trivial SPA not based on a framework will end up inventing one eventually that solves the very same problems which were already solved for you. Examples being history management and back button, state management (especially if you prefer immutability), and server side rendering.
On the other hand, if the app is not an SPA, you probably don't need the framework. Both history and state gets managed on the server to an extent. However, most apps are better as SPAs rather than these hybrids. Informational websites being the exception.
I agree with this. If you're augmenting a traditional request/html-response web app with some JavaScript functionality, a lighter weight view library fits the bill nicely. But, if you're developing a SPA that consumes an API, you might really enjoy what a more holistic framework provides in terms of code structure, front-end data management, and just general guidance on how to do certain standard things, like basic CRUD.
The key is the single directional data flow. It was purposed in Flux, made better in Redux, and is used in Angular as well.
If you're writing a large web app, the dependency injection part of Angular 2+ isolates your modules much better than Redux. You won't need a single file with action creators. Each service can contain its own information.
Though not a feature of Angular, Observables are the baked in method of HTTP. Using Observables are far superior to Promises. You can compose Observables and make the callback part of javascript a lot easier on you. You can also cancel Observables, which is not possible with promises.
One of the things I miss with React is JSX, however, it's not so bad. There is even a mobile framework called nativescript that allows you to write Angular 2+ code with Native UI.
People jumping on the Angular hate train are mostly riding the vapor from Angular 1.X. The new framework has been done very well.
The biggest problems with Angular2+ is that they called it Angular, and had a terrible release.
It's not Angular, it's a completely different framework. They rode their own hype train and it's made searching for tutorials, examples, libraries much more difficult.
I was lucky in that we didn't start our project until after the true release happened, but having such a long alpha, beta, and release candidate stage really hurt momentum. Articles and tutorials written before June 16' can be completely useless with the amount of breaking changes.
With that all said I'm really liking Angular 2+ with ngrx (redux). The problems only really appear when I'm trying to bring in other libraries as they haven't been written well.
This is my single biggest problem with Angular 2. It's not Angular, but in calling it "Angular 2," they effectively killed off a powerful framework which had a promising future, all while basically hamstringing Angular 2 from the start for (at least) the reasons you mentioned.
Do you mean lighterweight as jQuery or VueJS/React?
I ask because I'm having a major FUD of using VueJS in a small (tiny) project - I don't seem to be able to think in those terms yet, and I don't really use npm (those starter projects generate 1000 files...).
I'm from the time when you would just list JS files in the HTML..
Can't you use supporting libraries for more advanced stuff? Use Vue for the view layer, vuex for state handling, vue-router for routing and vue-resource for ajax, I feel that it is faster (as in dev learning time) to write an app in Vue without knowing any basics of Vue/front end dev world, I know this because I wrote this app, http://github.com/thewhitetulip/Tasks-vue as I started to learn Vue from the docs, later, I started to write a tutorial as I learned it, https://github.com/thewhitetulip/intro-to-vuejs/ because there is no such resource which taught from the newbie side.
I didn't re-invent the wheel, it is just like what we usually do with Go, we don't use a framework, but a toolkit.
> Examples being history management and back button, state management (especially if you prefer immutability), and server side rendering.
Maybe/maybe not, I use a Mini-SPA approach where I pass down libraries.js, bundle.js and foo-page.js (all minimised and such) on the initial page load I pull the data and pass that down as well (avoiding the round trip).
With that approach I get most of the benefits of an SPA in terms of behaviour but without having to use client side history management and I don't break the back button.
I still get to issue calls and such and the actual orchestration of the page side js is done with a very light class that each page extends from that has just a handful of methods.
Component orchestration is managed with pub/sub.
I've found it an extremely nice way to develop, there isn't a massive duplication of code and it's very easy to reason about, it lacks a few of the benefits of a pure SPA but has most of them and the separation is very easy.
I know you just listed some examples but I think many on HN place frameworks too highly. They're useful if they can make you more productive but many of the items they cover are not that difficult to substitute or attack from another angle.
> Examples being history management and back button
This is already built into the DOM API since HTML 5 (you can use hashes if you want to go old school as well). So you don't need any special library or framework to handle this for you.
> state management (especially if you prefer immutability)
Well, depends on what you mean by state management. Do you mean if you go forward and back the browser will reload what you already entered? The browser will keep state in some scenarios. In others it's simply storing it and reloading it.
It's not like this is difficult or anything. Most frameworks require setting this up in various ways anyway.
> server side rendering
I would argue server side rendering is far easier without a framework. Without a framework you can load templates from the server side that have data already injected and ready to go. The JavaScript front end just deals with it.
> I really think for most cases you only need a view library instead of a heavy application framework.
You may not even need that if you target modern browsers. You can componentize your code using Web Components (or Polymer) and optionally drop in a data management library such as Redux or MobX, and that's that. If your application mostly consists of plain HTML pages enhanced by some JavaScript widgets here and there, that's more than enough.
That said, I don't think GitLab falls in this category of applications, and I honestly feel going the full-blown SPA route with server-side rendering will work better for them.
Unfortunately for GitLab, they've locked themselves into a position of trying to compete directly with GitHub. If GitHub has instantly smooth transitions between page loads while browsing a repository, then GitLab is going to follow suit. It's really hard to be competitive while ignoring the nagging thought that "competing requires copying the competitor".
Performance matters - a lot. It's often overlooked because its effect on users is more unconscious than consciously noticed, but even small speedups greatly affect user motivation, as measured by any number of blog posts about "page load time" and "conversions".
However, "instantly smooth transitions" may not require using JavaScript. According to the blog post, GitLab observed a performance increase after ditching Turbolinks[1]. Indeed, sites that use JS to speed up page loads are often compensating for what would otherwise be an excessively slow load, due to having lots of scripts or whatnot. And that's only a partial fix: the user still experiences that slow load whenever they come in from an external site or open links in a new tab/window. If you can make "real" page loads fast, you avoid that problem.
[1] ...though it doesn't seem to have been measured very scientifically - to quote from the pull request: "I thought I noticed that pageloads were a lot more snappy, and one other reviewer said the same. Not the most rigorous way to test performance, but it helps."
The irony, of course, is that GitHub doesn't use any of the JS framework complexity that people here seem to think is necessary. They use jQuery and PJax.
Sometimes I feel like 95% of the thrashing in the JS world is from people trying to fix the wounds inflicted by the previous Hot New Thing...
Performance is really important, especially to user experience. We want GitLab to be fast, independent of the scale it's used at.
Right now, GitLab is fast and snappy for people that self-host it, but GitLab.com is not and we're not happy with that [0]. Making our front end performant is part of that and I'm happy our engineers have been working hard on that.
We have been using Prometheus extensively to monitor speed of transactions on the backend and I'm seeing a strong push to more monitoring to front end monitoring as well (I owe you a link here).
After a few hours of Vue / Riot I could sit and begin writing a full fledged app.
React for me was a bigger barrier to entry, i kept running into road blocks and searching google how to do things then everything is like "you need flux" or all these other things and I just got more confused and frustrated. Once you know it, its great, powerful, fast, a pleasure to use.
But I still prefer vue/riot. Simple easy straightforward.
I'd only heard of Vue as a name before this, but I followed the link to the documentation, which looks fantastic:
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
> Hello Vue!
> This looks pretty similar to just rendering a string template, but Vue has done a lot of work under the hood. The data and the DOM are now linked, and everything is now reactive. How do we know? Just open your browser’s JavaScript console (right now, on this page) and set app.message to a different value.
I guess that didn't take any extra work to setup, since it's a fair assumption the Vue docs are rendered with Vue (!) - but a really easy yet nicely motivating introduction.
Obviously this isn't too tricky with 'vanilla' JS, but there's certainly more ceremony involved, and I'm sure the templates can be more complex such that the JS/Vue contrast would be much greater.
> I followed the link to the documentation, which looks fantastic
It is fantastic, and engrossing.
After I said that this morning I tabbed back to the docs and read through 'cover' to 'cover'.
Great docs, and looks like a great framework - I think that I could read through and understand the whole thing with very little JS knowledge is testament to that.
The Vue docs are seriously amazing, I couldn't rap my head around React fully because its docs just weren't very good (though they've improved them since I last tried).
vue feels to me like a condensed knockout. i still use knockout on some projects, but have used vue on a couple new ones too. as much as I'd like to see knockout progress - simplify a bit more to be more compact like vue, i'll take vue if that never happens.
anyone using knockout looking to migrate, vue is a worthy spiritual successor imo.
Do you end up using View Models in Vue just like you might in Knockout? To me, a big benefit of React is making that translation step implicit; I like the idea of View Models but in practice I'm just schlepping a lot of data around between the models and view models.
It feels like I'm using view models, but I don't think I am. The idea of a 'vue object' ties some metadata, data and methods together, which seems like a somewhat tighter coupling, but also a bit more pragmatic (less "schlepping").
I'm no expert in either, but one of the things I liked about knockout early on was that it was pretty straightforward to decorate existing pages with knockout functionality, and vue has been the same way. Technically react may be the same way, but it never felt as easy as vue or ko. (I've only recently done some 'hello world' stuff in react, so again, no expert) I do have production code with knockout in multiple project spanning back about 4 years or so, so that's where my current comfort-zone is, but vue is starting to replace that.
Heh, after a quick look at the examples I tend to agree.
Looks actually a lot like durandal (lifecycle hooks!) plus the knockout.punches syntax enchancements (the local filters look nice!), minus the dreaded parentheses. :)
Sadly I think the problem of GitLab's sloweness is not the UI framework :(
We are 3-5 users on gitlab ce and use 3GB of memory + 4 CPU cores (vCPUs from XEN) and it still feels slow. Even big Java Applikations use less memory, for that amount of users.
I recently needed a simple self-hosted git web interface for about 3 people, and I only have a cheap 2GB RAM VPS that also runs other things. After looking at gitlab's requirements, I didn't even try.
Nothing wrong with responsive UI, just don't create something meant for phones and then just scale it up to a larger screen. Which is what bootstrap, material design etc. often end up looking like.
We agree. It's not just the front-end. We had problems with bot the front-end and back-end. But we're working hard on making things better / more performant on all fronts.
I run a private gitlab used by 2-4 users regularly and a few others irregularly.
The biggest issue is the sidekiq process. I've had so much trouble with it hanging that I'm starting to wonder if it's a problem with my VM. But it's one VM in a big vSphere environment and no one else is having problems.
Have you noticed Sidekiq hanging? When it hangs it often says it's using all its jobs, and you can't shut it down without forcing a kill signal.
Yeah, being unable to host Gitlab under 512MB is just too bloaty for me. I know Gogs doesn't have this issue for the same features I use. I still use Gitlab though because it's the mainstream.
well we use it because alternatives that costs money always takes years to finish a simple feature and tell people that they can extend it via their plugin repository.
and we also use it for their CI integration. It's just simpler than setting up a Jenkins instance for simple jobs (well gitlab ci is slower but not so much that it is painful)
well gitlab ci is slower on our machine than jenkins.
also push based ci might be better for performance when having many workers. while gitlab ci is pull based which can net in negative performance.
of course pull based is way less painful when nodes go down/etc..
actually the biggest problems of slowness also comes from docker and caching. I think our docker setup for jenkins/gitlab-ci is not equal. for some jobs we will probably migrate away from docker, as soon as we are able to have a good story for running parallel tests.
Totally agree, maybe they would need UI polishing to make it more user-friendly a la "GitHub". But first priority definitely should be backend speed improvements, not frontend.
Vue.js is just a better option for every-day development in smaller and mid-sized teams, it gives more freedom working with arbitrary html, which is huge, it also gives easy start - you don't need compiler to use Vue across your legacy codebase. React is a good thing if you are a hard-core fulltime frontend dev in a big team, I guess. That's why potential of Vue.js popularity is ~25-30% of jQuery worldwide usage while React will probably might get 5-10% at most - that's just my impression after using both React and Vue. http://pixeljets.com/blog/why-we-chose-vuejs-over-react
"Legacy codebase" generally refers to anything that doesn't an meet an organization's current standards for new development, especially to the extent that that limits maintenance efforts.
That standards may move faster in web dev doesn't make the use of the term any looser there.
That's right, in the web dev world "legacy codebase" is 3 or 4 years old, created by a previous team who all quit once they finished the rewrite of the previous "legacy codebase".
3 or 4 years? Seems generous. Lately it seems anything more than a year old is "legacy" or "technical debt" because the team is now using other frameworks or libraries.
Our entire JS is 800kb not each page. So we are splitting it on a per page basis. Everything including issues, MRs, file browsing. There was 800kb of JS in the entire app before I joined as the first FE Eng. There is jQuery and other libraries and our own code. That was the reason we wanted to remove Turbolinks. So we don't load all the JS for the entire app at once. We want to load things on demand.
Funny thing, I have built a full fledged production 2d/3d application in JS. It was less complex than what GL has to do, and it was 670kb fully minified and obfuscated. We are constantly looking for ways at GL to make our file size smaller and our JS faster. It is something we are actively putting our time towards.
Why do you need to use Turbolinks, when you can just do a normal page load, and set the correct cache headers for your javascript bundles, to stop the browser re-downloading the same script.
This isn't specific to GitLab or GitHub, but turbolinks, pjax, and friends are really useful when you have a lot of setup that can be shared between pages, i.e. initiating a websocket connection, rendering a header with notifications and an avatar in it, decompressing and parsing your js and css, etc., and you don't want to implement a single page app.
When I refresh the GitLab sign-in page in Chromium, I see that the initial page load takes 40ms to parse css, 250ms to parse and execute js, and then another 70ms after DOMContentLoaded. This is with a warm cache. It's not unreasonable to think that turbolinks might save about 300ms on page loads, which is a respectable performance boost.
I completely agree, thanks to the webpack move it will now be a lot easier to take control over the chunking of the JavaScript. There are a few things in place already but it can be thinned out a lot more now.
Can someone explain why someone would choose Vue over React (or one of the clones)? When I looked at the docs for Vue it reminded me of my Backbone days.
I'm mostly a backend Rails developer, but I've spent the last 3 months developing stuff with Vue, Elm, React, and Angular 2 in an effort to see which of the front-end frameworks I would like best (I messed with Ember a year ago but haven't had a chance to revisit since). To me it seems like React is about putting logic in code instead of templates/markup. Vue is more in the vein of Angular, where you have logic in your templates/markup. So it's sort of a question of what you feel more comfortable with, the style of Vue or the style of React.
Instead of Vue or React, you might choose Angular 2. Vue is sort of touted as "Angular done right". I did enjoy working with Vue (I actually enjoyed working with all of them), but I think Angular 2 may be "Angular done right". However, Vue seems to try to be more lightweight and less of a framework than Angular (1 or 2). It has this in common with React. I think both Vue and React would be easier to start introducing into an existing app incrementally. Angular 2 seems like it's more of a framework/holistic choice. It has this in common with Ember, although this is true of Ember to an even larger degree.
I was really excited about Elm after listening to The Changelog episode #218 (https://changelog.com/podcast/218). Elm is in the style of React, but the flavor of Haskell. For my part, I had a hard time with the syntax and functional approach of it from the get-go. It was very new and awkward to me, which was a speed bump to my adoption. However, I felt like it held the promise of allowing potentially better/ more maintainable code. Evan Czaplicki (the creator) and Richard Feldman (a prominent evangelist) both talk about how the Elm language and style led to more effortless refactorings in larger front-end codebases they were working on. Sounded really good to me! But, I eventually ended up leaving my Elm journey and starting my Vue journey because the Vue documentation was so good (comparatively) and the style of Vue felt more natural to me. It kind of came down to the question "how do I do CRUD with this?". For me, the story was easier and more fleshed out with Vue. Currently, I'm working with Angular 2 mostly because it had a more definite answer to this question than Vue. And, the testing situation seemed way more fleshed out than Vue's (at least at this point). But, I plan to check back in on both Vue and Elm in the next year or so to see where they've landed. I understand what people are saying about JavaScript fatigue, but there's also so much exciting and cool stuff happening in this space right now. It's hard not to love all this innovation.
Elm is a language, but it's sort of automatically a framework as well. There's a function in the standard library called Html.program that takes four functions as arguments and returns a React+Redux style application from them. The Elm runtime exists solely in the browser and expects your main function to return some HTML, which it will display using a virtual DOM. They call this pattern 'the Elm Architecture' (TEA) and recommend that everyone use it. So it's like having a really lightweight framework baked into the standard library and indistinguishable from it.
Those four functions are view (take a model and return some HTML, like a React top-level component's render method), update (take a model and a msg/action and return a new model, like a Redux reducer), init (an initial state) and subscriptions (a list of things to watch for changes and automatically create msgs/actions from, like mouse movement or websockets). When you run a program, it feeds the initial model into the view, and renders it. HTML elements can create messages (dispatch actions) based on DOM events, and subscribed things (like websockets) can also create messages. Every time a message is created, it gets fed into the update function with the existing state, and you branch on the message type to figure out what the new state should be. Then that new state is fed into the view function again and the result is diffed against the virtual DOM and the optimal update made.
The biggest differences between React and Elm are that you don't mess with lifecycle hooks and that you don't repeat this pattern for every sub-component. Instead, you just write lots of small functions that take a model and return some HTML, and you can call those from your top-level view function -- a bit like building everything out of React stateless components.
Writing any Elm code feels a lot like writing React, but with much less boilerplate, reduced complexity, excellent error-catching, and static typing.
Oh, thank you for the detailed answer. I'm a bit ashamed to say that I really hate JS the language, but Elm sounds like a very nice alternative and potentially very interesting to play with.
Elm is a language, but it also dictates a very specific way of structuring your front-end application. This style is very similar to Redux and other such immutable state -> render -> actions -> reducer -> state flows. I can absolutely see why someone would compare it with front-end frameworks.
So, I'm still a noob with this stuff, but it's my take that Elm is both a language and a front-end framework. It's a language that compiles down to JavaScript that also gives you a React-like toolset to develop front-end code with.
The most annoying thing in Elm, not the language itself but their community. People complain about openness, elm packages can't grow as fast as contributors want to see.
I do not want to write a long story of composability and fancy types that haskellers want it and Elm doesn't have. But thoes are also big blockers
If you already know react and are happy using it, then there's no reason to use Vue.
But if (like me) you were never quite able to figure out how to use React (especially all the build tooling that's suggested in every tutorial), then Vue is worth a look as it's incredibly simple to get started with and easier to learn.
I find it especially appeals to people coming from a place of familiarity with html and css (whereas react seems to appeal to people with more of a straight-up programming background). YMMV
I think this is problematic because people don't differentiate between React and the React ecosystem. Plain old React is just as easy (probably easier) than learning Vue. I always recommend the official React tutorial (https://facebook.github.io/react/tutorial/tutorial.html) before even thinking about Redux or Webpack or whatever.
Of course it's subjective, and different people coming from different backgrounds / experience levels find different things easier than others.
But... that tutorial you say you like to show people utilizes jsx, which needs to be compiled with something (right? Or does react do the compilation automatically at runtime now and I missed that memo?).
And for people coming from a place where they are very comfortable and familiar with html and css, and maybe a light sprinkling of jquery on top, Vue is way more approachable than the tutorial you linked to.
create-react-app is our recommended way to build simple React apps (and some complex ones). It has no configuration and is designed to be very easy to set up.
(My understanding is that Vue templates also need to be compiled -- is that incorrect?)
I wrote the tutorial. Could you give any suggestions on how I could make it easier to get into?
Not the OP, but I'll state the obvious on their behalf.
The number one thing that you (and Facebook) could do to help people learn React, and combat the perception that it requires overly complex tooling, is write a tutorial that shows how to use React entirely in-browser without any build toolchain. A static HTML file, some <script> tags pointing at a CDN — done. No distractions, nothing to download, nothing to install, nothing to run, just a JavaScript library that makes it easier to write view templates.
It would make it even easier to get into if that tutorial were written entirely in ES5, but you could use babel-standalone if you felt that JSX and ES6 were important enough.
Thanks for replying! Our official tutorial was actually exactly that for _years_, but it didn't seem to help much. I get the sentiment though and maybe we can find another way to make it work.
Offering an alternative point of view: I would really like if the tutorial at least pointed towards documentation on what do I need and why, and the right way to set these things up between Babel and Webpack, as well as Typescript.
Maybe my use case is rarer, I don't know, but if I want to do things right, I want to understand what I'm setting up. Do I really need babel? If I use Typescript, do I still need it? etc...
I understand this doesn't have much to do with React per se but if these components are a definitive part of the ecosystem people work with, there is value in at least telling people where to find a high quality explanation for how they fit together.
I think this post is spot on. I remember having a quick exploratory play with React back when the tutorial was like that and I thought it was great. Then when I came back to actually use React in a project the tutorial had changed and all of the sudden it felt like a big learning curve. Vue had just been adopted by Laravel and I was able to get everything I wanted to do by just including some scripts.
I've since learned more about compiling and including other resources so could probably handle the React tooling and requirements now but back when I started it was a big stumbling block.
This is why I am using Vue and never gave React a second thought. Everyone "says" JSX is optional but there is no practical way to invest in React without having to deal with it.
JSX is a breeze though. The trial-by-fire for me was handing a bunch of ugly components to our designer who only knew HTML/CSS/JS. He picked it up no problem.
And to me using JSX is infinitely better than have to use opaque template directives like Angular and Vue.
To get started with Vue, all you need is to include 1 javascript file, and it works with plain old javascript, all the way back to IE9. As one gets more advanced, there is the ability to compile templates, but that is an optional thing that no beginner needs to worry themselves about.
I took a closer look at your tutorial. It's really very good! And I like that you link to a codepen which gets people up and running without having to even create their own html file.
Tutorials speak differently to different audiences -- I imagine people used to building more traditional "apps" get a lot out of this one.
But speaking from the perspective of someone who spent years making html+css pages that had data piped into them from the back-end (PHP, Rails, etc)... the scope of the tutorial is somewhat overwhelming to me :)
It goes right into components, shared state, immutability, functional programming, history... to some people that is a lot of concepts at once. I think the appeal of Vue (to a certain slice of people) is that you can just add it as a "light touch" onto an existing html page. For example, show me one textbox who's value gets displayed in a div somewhere else on the page as I type, or one button that toggles the visibility of one image. Just super duper basic stuff, in very isolated and limited-scope chunks, and in the context of "easy dom manipulation" (as opposed to "building a game or app").
Both frameworks are the same with regards to compilation.
JSX can be used at runtime by including the babel browser compilation script. This is only recommended for development, not production. React can also just use plain javascript, although JSX is a much cleaner and easier to use with the rest of the framework.
I have a theory that every project eventually approaches a level of complexity reflecting the level at which a moderately intelligent person can't understand it any more. I think of it as a "complexity budget". So if you start with something simple (say, React) then people will just invent more layers of complexity around it to solve whatever the next layer of problems is (Redux, Webpack, etc). And they won't stop until the complexity budget is all used up.
I had the same problem, couldn't figure out how to use React, I started learning VueJS and in a week I had built a fully working app, https://github.com/thewhitetulip/Tasks-vue
Then you should look at Polymer. It is just DOM nodes (custom elements_, you can however compose complex applications with it without any trouble.
I feel its very straightforward way to build applications and most parts of it are handled by browser API's. It seems like a perfect middle ground between react/angular 2/vue - and you can still throw in redux or uniflow-polymer if you want.
whats the problem with using bower (apart being "legacy"), it suddenly stopped working?
Not all packages are on npm, i use mix of npm and bower without issues. When the JS community comes up with better npm will people stop using packages on npm?
It's like the ideal mixture of React and Angular. You can use more the template approach than in React (where everything tends to be a component). Footprint (size of libs) is also smaller than React while still having VirtualDOM and speed of React. What I also experienced: It's much simpler to add Vue to existing HTML code without the need of bundlers and build tools like Webpack etc. Also keep in mind that Vue ecosystem is more from one hand: Vue itself, the store (Vuex), the router... all from one single source and team and not cluttered from various teams like in React ecosystem.
React has no templates which is an advantage until it hits you with large bundle sizes. Every line of JSX is transformed into a longer JavaScript program.
I love that React makes developers more productive with JSX but there should be a way of outputting HTML for large template like React components. Browser are much happier dealing with HTML.
I've tried out both. I like Vue because I can work with standard HTML and augment it with Vue, whereas React requires using JSX. JSX is proprietary and HTML is kind of hidden. There's an additional mental translation when writing JSX.
Backbone is a structural JS library/framework. It gives your app a backbone. Vue provides data binding so your View(Vue) gets automatically updated when data changes. Completely different.
Backbone implements 1-way binding via model:change event + render(). Vue/React/Angular do various forms of diffing, which makes their incremental rendering more efficient than Backbone's.
It's good to see vue.js getting some love. I believe it would be the preferred Web framework these days if it had backing from FB like React does. Too many people fall into the trap of believing a tech is the best just because some big Corp sponsors it. I fell for Angular once for the same reason.
Disagree. React was released in 2013, but use didn't take off until Dan Abramov released his Flux implementation, Redux, in early 2015[0]. That is a full two years of a Javascript view library with the backing of Facebook where it didn't leave much of a mark vs angular.
Most of the projects that contributed to React/Redux becoming popular[1] were developed outside of Facebook - altho some of those developers went on to work for Facebook.
I'd also argue that it isn't the projects themselves that made it popular, but rather the design philosophy that React/Redux brings to a project that is popular. The Redux part is a Flux implementation, but the React part could also be seen as a "React" implementation - one that certainly has flaws and could probably be improved on much in the same way Flux has been improved on (there are other parts that could use this as well).
If you think of the React/Redux style as opposed to React/Redux the code projects i'd characterize it as an ad-hoc, componentized, purely functional and immutable architecture. But that is just listing characteristics, rather than capturing what it is about. Formalizing what it looks like could bring improvements to the ecosystem.
I'd also argue that big company backing has little meaning in web application development, unlike enterprise services, hardware and operating systems. I have two enterprise clients who both migrated from jQuery style web applications to Angular 1 largely on the basis of Google's support. They're now both migrating to React/Redux and have been burnt by Google's support - meaning two periods of developer re-training, prototypes, testing and then migrating code in just over a single year. There are similar situations with Microsoft's ASP.NET MVC although they're handling the transition much better.
[0] iirc he released it earlier, but first half of 2015 is when React + Redux "hockey stick'd"
[1] the term is definitely React/Redux - React isn't (and wasn't) as successful on it's own. Welcome to the new GNU/Linux.
A slight tangent: I'm not sure I agree with giving Redux all the credit. There was definitely already some momentum going when Redux was first released although it certainly acted as a multiplier.
It's important to remember that even when Facebook first spoke about Flux there was no Flux library. Facebook's Flux implementation came out very late and even then it pretty much only consisted of the dispatcher. There was no example project to look at so all the "Flux-likes" (of which there were many) tried to look at what FB had presented with an MVC/MVVM mindset and attempt to guess what they meant.
This Cambrian explosion of "Flux libraries" (few of which really deserve the title) had mostly fizzled out by the time Dan presented his talk on time travel debugging (i.e. Redux). I guess without Redux the community would have settled on something with a lot more ceremony until Rx gained traction -- we certainly wouldn't have seen libraries like MobX and I'm fairly sure Apollo would have looked quite different. Maybe Relay would have been more popular.
That said, your core argument still holds: the React ecosystem, although heavily sponsored by Facebook, is not dependent on Facebook by far. There are alternative engines for JSX that aim to be compatible with React to varying degrees (e.g. Preact and Inferno) and Relay is the only state library out there that's directly tied to Facebook the same way React is.
Additionally because it's not a monolothic framework but an ecosystem of libraries, React is more adaptable to change. If React were taken in a direction the community disagrees with and make a hard cut like Angular 2 did, Preact could evolve independently and continue providing compatibility layers for React users.
On another tangent: the problem with React/Redux is that neither React nor Redux depend on the other and there are other combinations (like React/MobX or Preact/Redux) that share the same general ecosystem. But I guess the same could be said for early GNU/Linux. I've settled on just talking about "React" the same way I settled on talking about "HTML5" when that became a thing ("Is the new website HTML5?" "Yes, by definition.").
I'll take a stab, although I don't share the same absolute stance.
I've run the gambit when it comes to types of front-end projects. The React community has more focus on scaling React for large teams and companies. This isn't to say Vue can't do any of this, but there is a clear focus in the React community. I need to do isomorphic rendering because of SEO, there is a lot of React documentation on that and very little for Vue. I need static analysis for my code to prevent errors, Flow answers that. I need a replayable state for debugging errors, Redux gives you that.
None of what I mention about React is its sole domain. You can list off many alternatives.
Reading through why people choose Vue, many common needs come up. The one that I find interesting is needing a system that Designers can understand because they code up the HTML and CSS. I doubt that is something that comes up with React teams.
In my opinion, if you require a framework, Vue and React are two great options. It comes down to various small differences about your team needs. (Please stay away from Angular though.)
I love both React and Vue, but I feel the need to step in and defend Vue a little here.
Of the 3 points you listed, Vue has a section in the official documentation dedicated to Server-Side Rendering, ditto for using it with Typescript for static typing, and it even gives you replayable state with Vuex (the official redux-style library for Vue).
If I make a typo in the name of a component or the name of an attribute used in a HTML tag property, Typescript will catch it. Since Vue & Angular uses template strings, TS can't do the same check.
This makes catching errors and refactoring easier.
I used to prefer Vue, but since I've discovered Mobx, I only use React now. It took me a lot of time to properly learn the tools, but I'm pretty happy with them now.
This. I just had a look at Vue and everything looked fine so far, until they started with two-way-bindings.
Two-way-binding failed already long before the web and SPAs. Many desktop GUI frameworks provided two-way-binding, but this concept constantly failed to deliver on its promises. Not sure why frameworks keep repeating this well-known anti-pattern.
I'd prefer framworks like React or Riot any time over two-way-binding.
1. Bad Two Binding i.e. Two way binding between components. Vue2 and most of the UI frameworks shun this.
2. Good two way binding i.e. Form model binding.
Because form input can actually come from two sources (user input and javascript). this is naturally two-way and this is why frameworks continue to keep it.
I think the second one isn't really a valid example. There are very few situations where you both want to have state mutations discard what the user has already entered and reflect user-provided state in real time. In other words even if it's supposedly "two-way" you don't actually want multiple inputs to share the same model and you likely don't want to represent the data the same way the form control needs to represent it internally.
As an example, let's say you have a formatted text input field that can be used to enter a decimal number. If the input contains no decimal separator, the decimal part is implicitly zero. But if you just use naive two-way binding with an actual decimal value this means you'll get in the way of the user trying to manually enter a decimal value (especially if the user tries to delete the decimal part starting with the separator).
As soon as any information is lost during the bind in either direction, you still need to explicitly think about where you want the data to flow into and out of the form field.
The archetypical example of two-way binding is definitely the auto-generated CRUD form that lets you edit a model in place, but IMO this is a tiny niche in practice because it falls apart as soon as you want to do anything non-trivial. It's great for prototypes though.
EDIT: To clarify, I think you're talking about two-way binding a form model to form inputs. But calling that two-way binding from an application developer's POV is kinda redundant because you still need changes from the form model to propagate outside the form in a more controllable and predictable way than two-way binding offers, so the two-way binding of the actual form fields becomes an implementation detail.
> Many desktop GUI frameworks provided two-way-binding, but this concept constantly failed to deliver on its promises.
Can you elaborate on this? The last time I wrote a native application was 6 or 7 years ago using Cocoa and Objective-C. If I remember correctly, Cocoa had a mechanism that was similar to two-way binding. Have things changed recently? What do modern iOS/Mac applications use?
Cocoa Touch (iOS) got rid of bindings altogether and you manage updates manually (although I use a bindings library to emulate the old OSX bindings support in one of my apps).
Not sure on macOS, bindings may still exist there.
That's exactly my point. The concept of bindings (in the sense of two-way-bindings) hasn't proved to be successful - neither today nor in the past, neither on desktop or in the web.
As a more general throught:
When comparing concepts or patterns, there are often discussions about which one is better, comparing different but almost equally good options. Choosing the "best" one is hard. So the list of advisable patterns is constantly evolving and changing.
However, some concepts clearly didn't pay off over decades across a huge variety of settings. These anti-patterns are quite stable, and more or less just growing, not changing. It may make sense to collect these ones.
The "good" concepts may be subject to fashion and evolution, but the "bad" ones are stable and hence worth collecting.
Two-way bindings are great for prototypes because you no longer need to think about how your state gets from one place in your application to another, you just shove your mutable state blob into every last part of your application and the framework does the rest.
But what you lose in return is the ability to control when state should change and sight of where changes come from. In the case of POJO state implementations like AngularJS 1 it also means you have to constantly diff the state against what you've last rendered to be able to respond to changes nobody told you about.
AngularJS 1 actually tried to optimise this a bit but ultimately it needed to pretty much control everything asynchronous in order for that optimisation to work and more often than not that resulted in hapless beginners wondering why their changes aren't always reflected in the UI (answer: because nobody told Angular it should check).
So in other words, your state consists of big balls of mud that may change shape without notice and if you pass one of them to any piece of code you must expect it to do just that without any way to tell until it happens (and good luck trying to figure out where it happened exactly).
Compare this to the "one-way data flow" React made popular: your state is a bunch of impenetrable rocks that roll into your application, which can't modify them but can do whatever it wants in response to them (e.g. push pixels around on the screen). If the application wants different rocks, it needs to explicitly tell wherever they came from that they should be different, at which point the application will be fed a different (or maybe identical) set of impenetrable rocks again.
In a word this is basically the difference between mutability and immutability, taken to the extreme. Although there's nothing in React forcing you to use immutable data structures, the one-way data flow assumes everything it's fed is immutable unless you say otherwise, and you pass in callbacks to be notified when state should change.
On the other hand, in two-way binding your state is mutable and extremely malleable by definition, and thus the implicit expectation for every operation is that it may have changed the state.
As a side-note: React actually has a dirty little secret called "context" which is the equivalent of thinking with portals: instead of passing ALL the state into your ENTIRE application's root, you pass the state container to a magical Pez dispenser that wraps your application root and then each component can be wrapped in a container that knows about the dispenser and asks it for a specific part of the state. That's how React-Redux works among other things and it's not entirely unlike dependency injection (except it doesn't happen globally but only in the context of the specific instance of the application).
"at scale"? I hear this a lot of when react gets sold, but apparently most of the time people are using this in the old MongoDB "web scale" meaning, not when it comes to scaling up to complex interfaces (i.e. "we use it like jquery, but get lot of hits/s", not "this is our enterprise CRM desktop that's on par with your average single developer Delphi program").
> React has amazing reasons why it is fundamentally better than most of the other libraries for projects at scale
And yet somehow even on my quite powerful Macbook Facebook can halt to a freeze for me when scrolling long feeds or comment threads. One would guess that React would handle those scenarios gracefully, but that doesn't seem to be the case.
You seem to think that because Facebook's website uses React it's a React app. Facebook is no different from other continuously developed applications that evolve organically. In other words: it's probably not a good example for a "best of breed" pure React app.
I'm guessing Facebook uses React more on facebook.com than it uses React Native in their mobile app (I think there was an article a while back on HN about the ridiculous amount of packages in their mobile app, which is a testament to their policy of bolting on new code instead of rewriting the old unless actually necessary) but it's a safe guess to say that there's more to facebook.com's frontend than just React.
> For example, the profile page could be potentially very light, and there would be no reason for that if someone is linked directly to the profile page; it should load every single piece of Javascript in our project.
There are plenty of ways to do that with single Page apps; it's not a great argument against all single page apps, just poorly designed ones.
Sure! Multiple discrete single page apps are simpler to develop and maintain, especially for apps that have a lot of dependence on the backend. IMO it promotes a healthy (aka obvious) separation of concerns and provides flexibility. A UI framework like Vue helps us cut a lot of corners when we need to, but no doubt, not every problem needs to be solved using the framework, the ability to retreat to vanilla when you can is hugely underrated IMO, especially given the _promising_ future of vanilla.
I mean our profile page, there's hardly anything to it and it doesn't need JS. So there really isn't any reason for it to be a page of a single page application, let alone a JS app at this point. But with Turbolinks it was all part of one giant SPA.
An SPA has to be an "all in" thing though. If visiting the profile page then going back to the rest of the app is a possibility then the page load time is too high. SPA load times are only accepted because they are a one time cost.
That's not correct. A well-written SPA can lazy load components, take advantage of code splitting, load in modules asynchronously after the initial load. There are plenty of strategies to push the time-to-interactive timing right down. Webpack 2 supports multipage apps with individual dependency graphs for each page. SPAs have progressed considerably over the past few years.
The Polymer CLI by default builds SPAs that only loads the resources needed for each page. It doesn't require a very complex toolchain or advanced knowledge.
Open question: how well does Vue handle isomorphism? Our standard React template now for new projects is isomorphic, and we're porting old projects when/where we can.
There's an entire cottage industry of 3 to 5-year old series Bish startups porting Backbone // jQuery apps over to more modern frameworks. We are moving ours over to React at Plangrid (mostly done), Gusto is mostly done with their migration as well. Would be interesting to figure out how many startups are in this category.
We at engageSPARK moved from jQuery mess to Ractive.js, which we're quite happy with. The UI components don't cause us much stress, because they're conceptually simple. What gives us headaches now is the data flow (stores and actions using reflux), so we're now thinking about remodeling this, and while doing so moving to redux. The particular technology is less often the problem, but how it's used, and that's been true for us, too.
Sorry to be negative but GitLab's performance is embarassing :/ It is so slow and it's not clear why. Is this because of rails? Just seems very poorly engineered.
there is a difference between scaling a rails application when you are running a cloud business and running a packaged application on-site. I'm pretty sure nobody is running gitlab backed by databases like AWS RDS or something.
I have shipped large rails apps as packaged software for on-site install (using jruby). It's not easy.
I think the point is that Gitlab faces unique challenges because anyone can host Gitlab on their own hardware, so they're always trying to solve performance problems in a way that any typical user could also solve it.
Github on the other hand can use strategies solely targeted at their SaaS performance. It seems that Github also maintains more control over their enterprise version than Gitlab but I'm not 100% sure there.
https://github.com/github takes ~2.2 seconds, but by about 1 second has most of the information on screen and is simply waiting for the activity graphs.
I'm not aware of the performance bottlenecks with GitLab, but are there any plans to speed up the backend as well, such as moving to a faster Ruby implementation?
GitLab does have a plan to try and mitigate the bulk of pain generated from hosting lots of git repositories against a POSIX based filesystem by abstracting a layer of caching functionality and horizontal scaling. This project is called Gitaly[0] and is being tracked on GitLab.com
There's another github/gitlab clone called gigs that's implemented in go. Never used it myself, but if you want to save server resources I guess it's an option.
Is it something you'd consider? Even if it's not a performance bottleneck right now it's probably worth it to reduce server costs (more efficient Ruby implementation = fewer servers required to run GitLab.com).
Could be looking at serious gains, 3x over CRuby looks to be a fairly reasonable goal when using RubyTruffle (slow startup times can be mitigated against with SubstrateVM), and if that's not an option due to it being a fairly new project, it seems like JRuby could give a decent performance boost too.
Whatever an implementation or product claims, it's just not possible. While we could benefit from not having a GIL (something Truffle has if I'm not mistaken), it's not a free trade-off. For example:
* JRuby typically requires quite a bit more memory compared to CRuby, the same probably applies to Truffle
* Dependencies might have to be replaced if they're written in C. I personally don't buy Truffle being able to support all extensions. It's super fucking hard. I spent a few years working on Rubinius and had the unfortunate experience of having to deal with C extensions a lot. Supporting these properly is really, really difficult.
* JRuby might not work on all platforms we support. For example, we support Raspberry Pi's and the likes and it's not clear if JRuby would work there
Most importantly of all: a large portion of our slowness is due to badly written SQL queries, code that hammers the database way too often, and our Git operations. None of this would be solved by switching to a different Ruby implementation. The only way to solve this is to:
1. Solve the code
2. Educate developers so they don't make the same mistakes
3. Add linting rules and the likes so our CI environment catches any mistakes (where possible)
JRuby isn't an option for us because we use too many gems, many of which have compatibility issues with JRuby's implementation of Ruby. This is especially a problem for gems with C extensions.
I think Truffle is the most interesting new development in this realm, if it gets support for C extensions as they plan for it to, it may eventually be reasonable to run GitLab on it. That wouldn't be for a few more years though.
We didn't go with TypeScript because we were burnt by CoffeeScript before. People don't know TypeScript or CoffeeScript nearly as much as they know vanilla/ES6 JavaScript. It's easier to hire for and easier to get contributors for.
Surely the sourcemap is externalized to a separate file and only loaded if you attach a debugger, if the sourcemap is even deployed to prod together with the bundle at all (unlikely in my experience). 'source-map' produces much nicer traces than 'cheap-module-source-map', and both type of maps are going to be huge in any case.
Once Rails 5.1 comes out and we upgrade to it we'll probably switch to Webpacker. It was an awesome development in the Rails ecosystem and really verified our investment into Webpack.
sounds like he never gave vue a try because thats also how i felt before trying vuejs.
but once you go vue, you will be very happy you did. i see a lot of ex-react devs who tell similar stories, myself.
with the sudden rise of vue and just how fast vue is gaining traction, given the trends and lifecycle of frameworks, i wouldnt be surprised if vue over takes react as de facto of frontend frameworks soon. it really makes development much pleasant and faster.
The escalating abuse of the word "awesome" is like the overuse of dynamic compression in music. When every expression is fever-pitched, there's little room for interesting expression.
I also notice that the most shameless abuse of "awesome" seems to come from public-facing software developers, e.g. community managers and the like. It's become some kind of advertisement for a bland, safe, comfortable community where nothing is risked, and competition is frowned upon.
All right, I may have gone a little too wide with that, but AUGH, we need to try way harder to increase our expressive range if we're going to be writing articles that aren't exhausting to read.
I wasn't trolling - I'm serious. If you are operations are in this bad a state, is investing a bunch of money in changing JavaScript frameworks on the frontend really the best use of your capital resource.
Same company, you just have to choose where to spend your resource, and from the analysis it looks like the operations and management side isn't where GitLab chooses to spend it's money.
Sure. They probably will. Why should that slow down their front end dev? Or are you suggesting firing some of their front end developers to fund the ops guys?
Every time I see a post like this , I feel sad for being less cool. I try to learn a bit of the mentioned cool framework. Then I realise, how awesome my current set up is.
Is not it more important it works for your setup than have the coolest and newest framework running? Look at Gmail... it's internally really old, nevertheless very successful and good enough for the use case.
Agree. But when you are a startup, working on limited resources, you often worry whether you miss something, whether you are doing something the hard way etc. So it is not exactly 'sad about being not cool', but more like a worry on 'not using something that can apparently increase productivity'
Vue really has the best of both worlds. You can use it like old-style angular or take the component approach. You can just include the 71kb minified script and take off or you can use a build system with components - Take a look at Vue-cli: https://github.com/vuejs/vue-cli
I also am strongly against string references to model properties in your template. Again, it's much better to use tools that provide some static validation of what you're doing.
Give me React with TypeScript to help me make sure I'm passing around what I said I'm expecting to receive at each point as features are changed and added, and I'll be in business.
Honestly, I use React in spite of my opinion of Facebook.