Hacker Newsnew | past | comments | ask | show | jobs | submit | more rtsao's commentslogin

I hope this doesn't alter the current GitHub npm package registry policy where all packages must be published under a scope corresponding to name of the owning GitHub user/org. The resulting increased transparency and clarity of ownership will be great for the JS ecosystem.

The existing npm ownership model is markedly less clear and has led to several problems, including the transfer of package publishing rights to bad actors without anyone being aware. On the whole, npm accounts and orgs were always just an unnecessary abstraction that obscured the actual provenance of software, of which GitHub is the de facto source.


Does this mean using alternatives (GitLab, et. al) is not an option?

The worst option has been Elm's system where the whole package system requires you to not only use GitHub, but when GitHub in down (which isn't uncommon unfortunately) packages that weren't cached locally were inaccessible with no mirroring options.


Yes thank you! We believe namespaces are a good thing and will continue to promote it as best practice.

Hopefully we can integrate repository information to packages meta data such that you could be aware of a change of ownership even for a globally namespaced package.


I think this is the big reason I'm excited about NPM joining GitHub. I don't trust NPM (I'm not fond of package repos in general), but tying packages closely to their GitHub source offers significantly more verification potential that a package is in fact comprised of the source code for it, and that it hasn't recently turned hostile.


Did you evaluate TOML and if so, what were the drawbacks you identified for the workflow use case?


From what I remember, we did look at it some, but I can't remember many specifics, unfortunately. Looking at it now, I think that it wouldn't give us some of the flexibility that we want—for example, TOML arrays can only contain values of a single type, and for the sake of brevity, there were places in our configuration where we wanted to allow you to, for example, pass either a shorthand string or an object.


https://www.deconstructconf.com/2017/brian-marick-patterns-f... is an interesting talk on this topic, which is where I learned about Seeing Like a State. I've just finished reading the book and found the parallels between software engineering and the high modernist statecraft and agroeconomic policy discussed in the book to be quite striking. I thought the middle chapters were a tad repetitive, but overall it was a fascinating read and I would highly recommend it.


The Fusion plugin system is rather powerful and enables colocation of related/coupled code that would normally be spread across several places. For example, the Styletron plugin for Fusion (an integration for a CSS-in-JS implementation) will do several things:

* Wrap the application component tree in a React context provider component (which provides an instance that components will render styles into)

* On the server, extract rendered styles after SSR from provided instance and add necessary markup into the server-rendered page

* On the client, hydrate the provided instance from the server-rendered styles

* On the server and in development, set up a route handler that serves two assets, a web worker implementation and associated WebAssembly binary [1]

* On the client and in development, fetch and execute the web worker. Normally, this would be a somewhat difficult integration because of CSP-related issues with web workers, but because the plugin sets up its own route handlers, the requests will be same-origin, sidestepping most CSP issues that normally arise. Additionally, Fusion plugins can also modify response headers for requests, so if needed, CSP headers could also be set appropriately.

All the code to do this actually is related to a single concern, namely styling, but in a universal web app, such things typically requires the involvement of many different parts of the application lifecycle and both server and client code. Fusion plugins allow you to slice up the independent parts of your application logic in this fashion, somewhat analogous to how colocating HTML/CSS/JS for individual components in CSS-in-JSX is often much nicer than splitting apart component implementations across separate HTML/CSS/JS files.

[1]: This web worker generates debug CSS at runtime that maps rendered CSS to the source styled component definitions in JS using source maps, making it easier to reverse map the rendered CSS to the source CSS-in-JS when inspecting the DOM with the styles pane. https://github.com/rtsao/css-to-js-sourcemap


For folks who really care about performance, the easiest win is just switching to Inferno or Preact. You can pretty much leave your React code unmodified and get massive performance gains.


Easiest win for me was trying out re-frame[1]. Not only do you get the best performance out of react, to the point where the actual virtual-dom implementation doesn't matter, but you also gain productivity and since it forces you to build apps made out of 95% pure functions and immutable data, reasoning even at scale is still incredibly easier than anything else I've ever tried to build GUIs with.

[1]: https://github.com/Day8/re-frame


I've maintained a ~20k LoC re-frame app for a year and a half. The performance of Clojure's persistent datastructures with pervasive sCU gives you generally good performance but it's not panacea. I've debugged a hundreds-of-milliseconds freeze on laptops from a poorly written hierarchical menu and I get pauses of 70-100ms if enough data comes in on our main view.

Using it with cljs-time and storing times in the app state is a really easy way to shoot yourself in the foot perf-wise since that's based on closure's date object and two equal date objects are not identical. This fails the fast identity check but will pass the structural equality check so no vdom gets generated but the check is not that much cheaper than a diff.

This is also a B2B app where we have no demand for mobile use so I haven't had to do load time or mobile perf optimization. If I did, the first thing I'd be concerned about is the bundle size since the cljs runtime plus React represents a fairly sizeable amount of overhead.

Not to say that reagent+re-frame is bad, it's just not so amazing you don't have to care about perf. I think Reagent would run particularly well on top of Inferno since the library provides lifecycle events to function components and I did experiments back in April and June on Inferno with persistent datastructures to good results. I just don't want to maintain it.


I tend to abuse the fact that subscriptions can compose in re-frame to lower the work needed in order to react to app-db changes. The fact that you can namespace keywords make it easy to scale as well.

Its also easy to optimize if you integrate day8/re-frame-tracer. I've lowered the number of views touched by updates quite a bit using it. I barely put any pressure on React anymore.

The bundle size usually isn't that bad with full optimizations enabled. An empty cljs project strips the entire cljs runtime for one, minus one defonce. You can also pass a compilation constant to react to strip its debugging features; that's saving you a few dozen kilobytes as well.

I'm currently building a small app to display Twitch chat as a personal side project and it handles GamesDoneQuick's chat effortlessly. Performance has been great so far.


re-frame might be technically interesting, but you're switching to writing in a lisp, which is a very niche choice. That's not going to be an overall win for many people.


Considering Clojure's impressive adoption I wouldn't call it a niche choice anymore; it even seems to be a win for most people adopting it.


Can you provide stats on "Clojure's impressive adoption"? By my understanding it's still a very niche language.

The TIOBE index [0] fwiw (please debate) suggests by going from JS to Clojure you'd be switching from the 7th most popular language to the 47th.

In that 'top 47' there are only 3 lispy langs present, 'Clojure', 'Lisp' and 'Schema'. That suggests programming in lisps is a very unpopular idea.

[0] http://www.tiobe.com/tiobe-index/


TIOBE is a terrible indicator generally. More activity doesn't mean more people are using a language. I wouldn't work for anyone using it to make decisions :)

The Cognitect website[1] lists quite a few success stories using Clojure. I would trust the names in that list far more than TIOBE.

But really what sold me on the language was the quality of the libraries, the incredibly helpful community and its shared focus on simplicity. Reading about a thing is no substitute for hands-on experience; its hard to judge the trade-offs you're making without it.

[1]: http://cognitect.com/clojure


A simple warning: switching to Inferno using inferno-compat can currently give worse performance than react. I tested this recently when Inferno 1 was released and think it's related to https://github.com/infernojs/inferno/issues/548 The techniques outlined by Netflix should apply to users of Preact and Inferno too, so it's still an interesting article.


It would be awesome if you could give the Inferno team your feedback so we can help improve Inferno. :)


Inferno sounds interesting, I wish I could use it for projects. But React has grown to the point where there are components for it you can npm install and import in whatever components you want.

Should the Inferno community start porting over stuff to their ecosystem it'll be easier to sell to clients.


You can point 'react' at Inferno at build time. I believe there's a Webpack plugin that does this.


Yeah, media queries and pseudo selectors (such as :hover) are supported. These tend to be really important for critical CSS. Descendent combinators are possible but to a greater degree involve tradeoffs. I posted my thoughts on this on this issue: https://github.com/rtsao/styletron/issues/27#issuecomment-26...


Thank you! It was built with Styletron actually (you can inspect the source).

It was also built with the excellent Inferno.js [1] library to render static pages while also having a super fast full client-side app, kinda like what Gatsby.js [2] does with React.

[1] https://github.com/trueadm/inferno

[2] https://github.com/gatsbyjs/gatsby


Why overengineer something as simple as a blog?


For fun mostly. It's a passion project I did in my free time. I wanted to dogfood ideas, experiment, and learn.


Why not?


Someone submitted a proposal on how to support descendent/child combinators. It's certainly possible, but I wrote a response on why it would would potentially involve tradeoffs: https://github.com/rtsao/styletron/issues/27#issuecomment-26...


I actually wrote a separate benchmark suite [1] that uses Paul Irish's pwmetrics [2], so using real Chrome to check render performance. From those numbers, Styletron performed really well in terms of time to first paint and time to first meaningful paint. But I didn't include it in the blog post because I wasn't sure how best to separate the transfer time factor (pwmetrics is set up to throttle network speed) since Styletron critical CSS was so much smaller.

[1] https://github.com/rtsao/styletron/tree/master/packages/benc...

[2] https://github.com/paulirish/pwmetrics


I think the argument is that separation of UI components is a more true "separation of concerns" than separating CSS, JS, and HTML.

The implementation of a UI widget is ultimately a combination of CSS, HTML, and JS which are coupled to some degree, so by colocating them together, the component is easier to manage. But to do this effectively, you need some way to get around the global nature of CSS. CSS modules and CSS-in-JS are means of achieving this.

A good blog post about this topic is: https://medium.com/seek-developers/the-end-of-global-css-90d...


> the component is easier to manage

But you can still keep CSS in a CSS file inside a module folder. SASS or any other CSS build took could grab it from there.

> get around the global nature of CSS

That can be done with proper scoping supported naturally by CSS.

Local CSS is still not as bad as moving CSS declarations to JavaScript.


An additional problem is that even when CSS is properly scoped, you end up with wasted bits over the wire by sending down duplicated declarations. I did some cursory research using cssstats [1] because I was curious how many CSS declarations are unique. Turns out it's about 20-25% for most "big tech" websites.

Gzip helps reduce the impact of this, but Styletron's gzipped CSS is still much (40% or so) smaller than the other CSS-in-JavaScript implementations [2]. In some cases, the cost of switching to using a tool like Styletron might be justified by faster loading times in low-bandwidth markets.

[1] http://cssstats.com

[2] https://ryantsao.com/blog/virtual-css-with-styletron


Bandwidth was the major motivation for building Aphrodite, too: Khan Academy wanted to decrease the number of bytes required for the initial pageload. http://engineering.khanacademy.org/posts/aphrodite-inline-cs...

> We must deliver the absolute minimum amount of CSS necessary by only sending down CSS in use by components in the server-side rendered body. This rules out extracting all the CSS used in all of our components at compilation time, as much of that CSS would not be needed for the initial page load.

Colocating styles with components is a win, but, more importantly, styles-as-JS-objects was the simplest way to get this perf feature out the door.


Faster load times is bit of a stretch. While it's true that up to 40% sounds good, but we are talking about a few kbytes here meanwhile images penalize you much much more on load time. And what do we sacrifice? Mixing concepts that shouldn't be mixed in the first place.

Duplicated styles also compress better with gzip as you said. Do you think stripping a few kbytes is worth turning your whole process upside down?


You're absolutely right that you can do it with pure CSS. But doing a pure CSS solution usually involves some CSS methodology that you need to apply extremely strictly and consistently, which honestly can be a challenge, especially in large apps. Sometimes it's easier to just throw in a new selector at the end of your stylesheet and "make it work". Without discipline, things can get messy pretty quick.

The point of CSS-in-JS and CSS modules isn't that it's necessary, just that it makes avoiding these sorts of problems much easier.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: