Our long term plan to make GitLab as fast as possible with Vue and Webpack
about.gitlab.com
about.gitlab.com
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.
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.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.
Nesting dozens of items is fine. That single line was more of an HN comment format limitation. This might be a better judge of readability:
C#
JSX
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 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(...);
}
}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.
What limitation are you talking about?
var element = DOM.p(
{id : "thing"},
DOM.div(),
DOM.div()
);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.
When unobtrusive javascript became a thing.
> As an industry, we’ve already decided: HTML and JavaScript belong together.
https://medium.com/@housecor/react-s-jsx-the-other-side-of-t...
var element = hiccup [p {id: "thing"}
[div "first"]
[div "second"]]
https://github.com/lantiga/react.hiccupI 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.
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.
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?
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.
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.
I'm talking about things like
return (
<div>{
x.type === 'foo' ? <Something/> :
x.type === 'bar' ? (
<div>
<h2>More stuff</h2>
<Another data={x.data}/>
</div>
) :
x.type === 'baz' ? <Another data="baz"/> : null
}</div>
)
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.
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.
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.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.
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.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);
};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.
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).`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.
[0]: https://developer.mozilla.org/en-US/docs/Web/API/Element/cla...
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.
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.
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?
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 haven't written any higher order components myself, unless you consider parameterizing event handlers in props to be higher order.
"Good view layer code means that templates should be as declarative as possible, NOT that the view layer as a whole should avoid procedural logic altogether." - https://lhorie.github.io/mithril-blog/getting-over-a-fear-of...
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.
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.
There are solutions that use the same templating server and client side, but they are far from pedestrian.
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.
Yes, exactly. There's no way to do this on the server, so anything you do with DOM will be split in to separate server and client side worlds.
For example, https://github.com/git/git/compare/master...next will show you "base: master, compare: next" when you load it. But I can use the dropdown + autocomplete to update that value.
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.
In short, technology isn't the problem with most UXs.
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.
You are so smart, how come no one thought about that before.
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.
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.
I'm not sure what the reasoning is behind this.
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..
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.
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.
> 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.
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.
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."
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...
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).
The performance issues we plan to work on are in https://gitlab.com/gitlab-org/gitlab-ce/issues?scope=all&utf...
Out of curiosity, what was the straw that broke the camel's back?
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.
So, it was the right idea, and the Angular creators just got carried away.
<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.
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.
anyone using knockout looking to migrate, vue is a worthy spiritual successor imo.
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.
https://vuejs.org/v2/guide/comparison.html#Knockout has a very short comparison, but they link to a "todo list" gist here comparing the two sets of code: https://gist.github.com/chrisvfritz/9e5f2d6826af00fcbace7be8...
Setting up the gitea docker container was so easy (https://docs.gitea.io/en-us/install-with-docker/) and it only takes like 160 MB of RAM plus it's super fast.
Then again, I only needed the more basic features, so I doubt that's gitlab's target audience anyway.
https://gitbucket.github.io/gitbucket-news/gitbucket/2017/01...
running it is simply java -jar gitbucket.war
EDIT: also, the colors seem quite dull from those screenshots
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.
We have an issue specifically about this. https://gitlab.com/gitlab-com/infrastructure/issues/947
We're planning a bunch of performance improvements for 9.0, which is intended to make GitLab faster for everyone. https://gitlab.com/gitlab-org/gitlab-ce/issues?scope=all&utf...
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.
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)
The script that authenticates and picks up the job is a small Golang app. That's all. GitLab executes CI jobs immediately.
See the architecture and related links here: https://about.gitlab.com/gitlab-ci/#architecture
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.
We're constantly working on improving GitLab's performance, and we have a bunch of issues open for performance fixes/improvements we'll be doing for the upcoming 9.0 release: https://gitlab.com/gitlab-org/gitlab-ce/issues?scope=all&utf...
Also good backup strategy. :)
In my company, "legacy codebase" is referring to C code from the 70s that is still ticking today.
That standards may move faster in web dev doesn't make the use of the term any looser there.
"On GitLab, our pages would load an average of 20kb on each page load versus the full JavaScript file size of 800kb+."
What exatly takes 800kb? I don't see a 3d animation/game on every gitlab page...
IMHO the solution to all this craziness is just generate small mostly-static page quickly and do not have 200 onLoad() functions.
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.
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.
It comes with it's own drawbacks though.
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.
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.
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
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.
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.
(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?
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.
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'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.
And to me using JSX is infinitely better than have to use opaque template directives like Angular and Vue.
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").
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 wish they came out with a storage/persistence system as simple conceptually as the renderer.
Maybe that's a lot to ask for though.
React by itself gives me blue balls.
I started to write this tutorial, an example based guide, https://github.com/thewhitetulip/intro-to-vuejs
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.
It seems polymer 2 will support yarn. but until then, it is a no go.
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?
That's like saying just use Javascript for everything. Good grief.
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.
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.
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 think vue is a perfect fit for gitlab but not quite perfect for facebook or a more complex web app on the front end.
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.)
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).
They really are both great options.
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.
(Note: Just guessing what the commenter might have written. I'm a long-term VueJS user)
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.
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.
Naive one way binding is useless as well.
>two-way binding of the actual form fields becomes an implementation detail.
Kinda. In fact in Vue two-binding is a syntax sugar for one way binding and on change events.
The difference between them, is one requires less lines of code and is less powerful.
If you do need react-style form input, then you can do it that way.
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?
Not sure on macOS, bindings may still exist there.
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).
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.
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.
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.
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.
> We are not rewriting GitLab's frontend entirely in Vue.
I don't know where people get the notion that rails is slow.
I have shipped large rails apps as packaged software for on-site install (using jruby). It's not easy.
If your local database is slow and the app code requires lots of DB resources, then sure...but that's the app, not rails.
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.
We're working really hard on identifying the causes of our performance issues, as well as fixing them.
There's a META issue about this here: https://gitlab.com/gitlab-com/infrastructure/issues/947
You can take a look at an overview of our efforts here: https://gitlab.com/gitlab-com/infrastructure/issues/947
It seems like a git server storing objects in an object store would allow the GitLab SaaS to scale out better.
Damn you autocorrect!
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.
https://pragtob.wordpress.com/2015/11/30/benchmarking-a-go-a...
1. Replace Ruby implementation
2. ???
3. Everything is 3x faster
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)
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.
To all the people arguing about JSX: Vue 2 supports it. http://vuejs.org/v2/guide/syntax.html#ad
> if (IS_PRODUCTION) { > config.devtool = 'source-map';
Ouch! This will make for a huge bundle. See https://webpack.github.io/docs/configuration.html#devtool
Merge request here: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9028
Here's a list of performance issues which we intend to work on: https://gitlab.com/gitlab-org/gitlab-ce/issues?scope=all&utf...
Most of them are scheduled for 9.0 or 9.1
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.
Really? What's 'loads of time' here?
React is an engineers overkill solution. JSX is bluck.
I use mithril.
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.
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.
Great way to discourage companies from handling their data online in a secure way.
Seriously with SSLs as cheap as $4.99 per year, your pricing feels like its 1999 all over again!
*As cheap as Free Ninety Nine