HNHacker News
TopNewBestAskShowJobs

ryansolid

534 karma · joined February 4, 2019

JavaScript performance enthusiast and fine-grained reactivity super fan. Works on Marko at eBay. Author of the SolidJS. .
submissionscomments
ryansolid··on Why are React component libraries so complicated compared to Svelte?
This comes down to React ships post compiled assets generally and Svelte libs send precompiled. This makes it much easier on library authors but also is because Svelte has built in solutions. This has tradeoffs on flexibility. Now you can be as flexible with Svelte but then you give up this simplicity.
ryansolid··on Next.js 10
I remember thinking when I first saw Marko it's kinda crazy how unknown Marko is given how well they've been doing streaming SSR and Partial Hydration for years. At production scale at eBay.
ryansolid··on Next.js 10
Does Elder do SSR or only SSG? It's sort of crazy how automatic partial hydration is in Marko. You just write your code and it works. No extra consideration etc.
ryansolid··on If Not SPAs, What?
It's worth pointing out MarkoJS it was basically made for this case for eBay's eCommerce solution. It predates the Next.js of the world but offers similar experience except it's MPA first mentality with seamless isomorphic experience and full working partial hydration for years.

https://medium.com/@mlrawlings/maybe-you-dont-need-that-spa-...

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
I'm big on read/write segregation and explicit mutation. With simple signals you have this naturally. Once you move to a nested tree you can lose this. Keeping this control allows us to adopt immutability patterns and enforce unidirectional flow. To me this is the most sane way to deal complex reactivity.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
As is probably evergreen browsers to use all features. I use proxies which are notoriously hard to polyfill. It is possible to avoid them but I was not taking IE in mind after that. So while possible to support older browsers with Babel unclear what all the polyfills that would be necessary.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
You can use HyperScript(createElement) version. You just forgo the advantages of compilation - better dx(less need for explicit wrapping), better performance(optimized code path), and smaller bundle size (more directed code).

Solid's JSX does not compile to HyperScript like React. HyperScript is a different slightly de-optimized experience.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Volunteering?
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
I have the article for you: https://indepth.dev/finding-fine-grained-reactive-programmin... It's a bit dense at times but I try my best to cover the whole spectrum and how it relates to familiar libraries.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
The reactive graph is a push/pull system as it updates similar to MobX. This is a great article on the subject: https://hackernoon.com/becoming-fully-reactive-an-in-depth-e...
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
I think Hooks are genius truthfully. But they are definitely shoehorning something into a place that didn't expect it. You are calling these render functions with the purpose of creating new transformations every cycle, and the injection mechanism has to include the initialization the first time. So you basically have these slotted things that allocate memory every time to just use what's cached most of the time.

Now don't get me wrong I've benchmarked Hooks like crazy and I don't think they are much consideration on performance at all. It's just the mental model of always update on the outside with bubbles of things that don't update creating these closures is a little unnatural. By comparison the mechanism they ape (fine grained reactivity) works exactly the opposite way. You just need to be aware the stuff outside doesn't update. Wrap what needs to be updated. Done. There are no out of date closures. No inconsistent mental model. It's as straightforward as registering event handlers.

Still I have to admit the solution is genius. They have managed to get 90% of the benefits with simply repositioning things. At one point this was one of my biggest arguments against React. People didn't appreciate it before hooks. But can you imagine knowing you could write applications this way years ago and trying to convince someone using React classes there was a better way? I just sort of gave up and did my own thing.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Yeah I guess I mean more I don't understand what it takes mechanically to support those types of transitions. It makes sense to me but I also feel like there would be a lot of details in a generalizable solution. Super interesting though.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
It's not unexpected at all. I've had several template library writers reach out to me about the potential here. And there is some. The challenge is figuring out how to hide the reactivity in a way that your end users would be happy with but still benefit. I think it is an interesting challenge.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Yep. I agree in practice Solid has some work to do here. The basics are think are reasonable in that we are dealing with your expressions in the template and real DOM nodes. So just drop a breakpoint in that sucker. Sort of return to how simple that was in jQuery/Backbone days.

It never is that simple mind you. I have an open issue around Dev Tools etc... We need to do better given the expectations of modern JS libraries.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Yes and keeping the order of application. I actually played with this for a bit. Early Solid let you basically codify mutations you could send in as data. I thought it was interesting to do something like Redux where instead of producing the next state you produced the mutations that would be applied, and then applied them at a granular level instead of diffing. But when you add time into the picture you actually have keep track of more. I'm not saying it's impossible to tackle this just the people I know who have been working at this always hit limitations where they need to fall back to diffing anyway. I think it would take some doing to determine where the book keeping cost would be worth it. It is rarely as simple as more granular is better.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
It comes down to control and immutability. I know not everyone agrees with this but I believe it's fundamental.

You can use the "Immer" syntax of setState if you want:

setState(s => { s.list.push(data); });

But in some cases it is more expensive. Like a splice will per row will trigger the proxy to tell you they've all shifted a position. Where as just setting the array only hits the proxy once. Sure Solid batches the updates from the call but it's still unnecessary tracking. Solid lazily decides whether state should be made into a reactive atom based on whether it is referenced in a tracking scope.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Awesome I think so too. I love exploring this space in general. It's really interesting to see how you can model problems this way. Reactivity isn't a solution to a single problem but a way of modelling any problem

Solid actually can work runtime only too but I do put most of my effort on the compiler since I can use it to overcome most of the classic shortcomings of the reactive approach performance wise (and DX wise) with a bit of consideration.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
I agree completely. I left an early github issue open with some examples. It just isn't my forte. I've worked with frontend guys who were mostly CSS ninja's and we never relied on framework mechanisms beyond applying some classes etc. I just lack the base knowledge to know what the expectation is here. I know Svelte has a very impressive system. I could look at doing something similar with Solid just not sure where to start.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Yep more or less. I was working with Adam, Surplus' author, for a bit before he didn't have time to work on the project further. I've take a different tact now with the reactive system and improved the rendering technique a bit. But he definitely deserves the credit for pioneering the JSX approach 4 years ago now. My initial JSX work was generalizing it for other reactive libraries and then it just grew to this.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
We use JSX identical to a Template DSL more or less. We don't use JSX at all like React does. That's why Solid so performant. It does similar thing to Svelte. We don't compile it into HyperScript. You can copy and paste html with one exception (void elements JSX makes you close input tags etc). But otherwise I support all the standard stuff pre-adding the dynamic bits. Solid supports `class` and `for` and `style` strings etc..
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
I mean it's basically the same thing as you do with React. You create lens functions more or less to handle get/set over the state object. Solid's setState has a lot more capability than React's handling nested updates with an ImmutableJS or Immer inspired API. The clever part here is immutable libraries already have API patterns to describe mutation so I just apply them here. So instead of spreading everything and cloning you keep the mutation locality for performance but keep the control of immutability.

Also don't be worried about copying the array that much. I'm doing that in the JS Framework Benchmark and it's still about the fastest with 10k items. The real key is identifying where you don't need to update the list at all just the items in it. That being said you can do an update without copying the array like this:

setState('list', state.list.length, newItem);

Granularity of performance isn't a silver bullet. Being fine-grained doesn't necessarily make everything faster (especially creation). The power is that granularity is arbitrary so it can be maximized to the type of situation, completely independent of component structure.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Yes you are correct. Use diffing here actually very similar to VDOM libraries. It was more performant(and consistent) than just propagating the change purely through manipulation of a proxy. Especially if you consider things like batching.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Generally implicitly either through proxy or get method read. Solid provides an explicit API as well.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Yes it's all the same thing. Your data is reactive and an be modularized. The renderer is reactive with the DOM basically being a side effect. There basically is no renderer just a reactive system with different types of data. It means there is an incredible amount of flexibility and raw performance.

The tradeoff is rendering isn't particularly special. So the systems consciousness of specific render specific concepts requires additional consideration. There is no "onMount". There are reactive lifecycles but they aren't particularly tied to DOM updates.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
I do return a proxy. It's just readonly. I really like the unidirectional data flow and explicit read write segregation of react. This adds so much control without having to add Framework like control mechanisms. I know it isn't easy, but it something that makes the solution elegant in the end. I think that passing data should also mean the choice of passing the ability to update it. That is a problem I have with almost all reactive implementations in libraries today. I think React has that part just right.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
I agree. I would love to do more. The truth is there is just so much to do. It's hard to find a balance between writing cleaner docs and say solving Async Hydration with Suspended Components. I had the luxury early on to prioritize the latter which is why Solid is so feature rich given how much of it needed to be researched and built from scratch. I always knew it would catch up with me. But that's a good problem to have.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Correct. The idea is that the derived state only updates when the underlying state updates. And the mapping to the DOM is just derived from that derived state. So list updates.. triggers bubble sort, triggers DOM reconciliation. The difference with Svelte is it sees it and the compiler writes the reactive code in the background. In Solid you just write the reactive code yourself.. ie.. `setState` etc. But it more or less works similarly.

It's like Svelte without abstracting the update mechanism. Which makes it a little more to get into at first but very similar to a library like React. The difference from React is that Solid knows exactly what you are updating so it doesn't bother with the other stuff.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
> In the JS framework benchmark suite, SolidJS and InfernoJS performance is almost identical (with SolidJS having a much larger margin for error in most tests).

I mean I agree with most of your post, but I'm not sure I would necessarily make that highlighted claim from the benchmark results. I mean the +- seems to be pretty run dependent for most libraries on there. And while I agree that the differences in performance is neglible, there is one. Solid is clearly faster in most tests even if by a small amount. Anyone interested you can look at: https://krausest.github.io/js-framework-benchmark/current.ht... And then isolate Solid and Inferno and then do a comparison against one library. It will color highlight the degree of certainty the difference is between the libraries in terms of significance of the results.

ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Thank you as always. Early days spent so much time justifying things, everything became these expositions. Time to tighten up.
ryansolid··on Solid – A declarative JavaScript library for building user interfaces
Thanks. I get criticism like "Why even make this? just use React." But it's so different. Yet I didn't want to throw everything away. People forget React came up when there were tons of libraries with similar reactive approaches and won our hearts and minds. It does a lot of things purposefully and it does those things well. We need to learn from the past it we are doomed to repeat it.
← PreviousPage 3 of 5Next →