natemoo-re / microsite

Do more with less JavaScript. Microsite is a smarter, performance-obsessed static site generator powered by Preact and Snowpack.

Home Page:https://npm.im/microsite

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Consider other JSX compilers

eyelidlessness opened this issue · comments

This is a significant stretch and I know it is, but I’m floating it as a possibility for an even more smol client side runtime. I have no idea how complex this would be. But I’ll state my case:

JSX is better than any particular JSX library

JSX is entirely a dev experience fiction (much like CSS-in-JS can be). It’s a declarative data structure DSL that doesn’t necessarily correspond to any particular implementation. It’s effectively a macro where you inject the macro implementation at build time.

This allows compilation to target arbitrary renderers and arbitrary reconciliation engines. Preact is awesome, but it’s explicitly tied to HTML/DOM (invalidating arbitrary renderers), and other optimizing compilers can challenge its size and performance even in that space.

It’s worth noting that I bounced off investigating Solid in favor of Microsite for my current project specifically because Microsite has first-class support for partial hydration but Solid currently has it as an open issue. I’ll also note @ryansolid works on the team developing Marko, which notably has truly automatic partial hydration (compiler optimized, not dev), but notably doesn’t support JSX. I feel like the potential for these two projects to meld is great for those of us developing mostly-static sites who want a JSX dev experience.

The challenge is that some of these implementations are ... esoteric and have their own limitations. Moreover, Microsite explicitly references/configures/wraps Preact with its own semantics in mind.

A potential mitigation of that risk is another promising project, JSX Lite which compiles a common JSX spec to a variety of backends (including Solid).

I have no idea if something like this is desirable for this project but I wanted to float the idea and see if you have interest. As I mentioned in #92 this would be something I’d be happy to work on.

(Also since I’ve @‘ed Ryan I’m super curious to hear his input on this if he’d like to join.)

And on that note, apologies to @natemoo-re for spamming your inbox this afternoon

JSX-Lite API was inspired by Solid mostly due to the fact that by identifying what was needed for reactive libraries you could serve both sides. You can sort of see a common API between it all that is what they are looking into. That being said I also think that's an ambitious task. In terms of being a generic base to unhinge from a particular library it does seem interesting and something others could embrace. But features would always differ, and even timing of similar looking primitives and update behavior. I've had many a conversations with it's creator about how to attack these problems. We had similar conversations in designing the latest Marko since one of it's goal is ultimately to produce multiple outputs like JSX-lite, just with a more expanded syntax.

As for the partial hydration story with Solid, honestly I just haven't gotten to it yet. I feel it's more important that I close the gap with Marko on the SSR parts first since it's also way ahead of the competition there as well. Solid's raw SSR rendering speed is already class leading and supports async streaming while rendering, but the route I went wasn't compatible with non-streaming and SSG so I have a different slower method that I want to replace before focusing here. I mean not that slow. It's similar to like Preact and React but it's no Marko.

I think there are likely concerns that go beyond the templating. By the same logic that says JSX isn't tied to a specific library it often means that any assumption that "it's just JSX" also isn't true and assumptions make the project tied to a specific library. I can picture something like a HOC or configuration be an easy solution for something like Solid with partial hydration (although obviously I was looking more at Marko for what the long term solution would look like), but I imagine it wouldn't be identical to Preact. And I think reactive libraries are a bit harder to hide. They come off a bit more opinionated about how you handle the non-JSX parts.

However, I also haven't looked at this project very deeply as of yet. I'm familiar with how Marko's compiler is used to achieve partial hydration but not how this project works. I will say this though. If you are just hunting size I think Preact is small and the difference we are talking about is probably not that big of a deal. There is performance potential but I don't know how important it is. I find a project like this interesting, and I think Preact is a good choice for it. I'd be willing to spend some time to understand what is going on to see if there is potential here for other libraries but if the goal isn't to try to support multiple targets it is probably good to just stick with one and go with that. There is definite complexity there. And Preact is plenty good for this use case.

@ryansolid thanks for weighing in! Having looked into your take on the other tech discussed, I think this is pretty close to what I expected.

I think I’ll wait for @natemoo-re on whether other targets are a consideration before I say more on that. But I guess I should clarify my use case/user story so at least we’re all discussing the same thing.

As an @eyelidlessness, I want to build mostly but not totally static websites (or even very dynamic websites with substantial static content), with minimal data and runtime sent to the client (I am not satisfied with NextJS style solutions where I send giant blog posts in HTML and in a big JSON blob to “hydrate” content that will never change). I want to build components (because I believe they’re a great way to achieve modular/reusable rendering) and I want to use JSX to express the render (because it’s an expressive and flexible data structure with lots of opportunities to determine render strategies per component). I want an efficient client runtime with good performance characteristics (although to paraphrase Ryan’s take, I’m not overly concerned about squeezing every last bit, Preact very well might be good enough for this). I want to accomplish this without a ton of conflicting tools and configurations, in a predictable way. I’m settled on manually marking things interactive but I have dreamy eyes about a compiler that does that for me with static analysis (see above RE: Marko). Basically I want a client side dev experience with a “you don’t need jQuery” user experience.

I hope the flow of consciousness is welcome.

My goodness could GitHub please figure out touch events? Sorry if I spammed anyone trying to see who thumb reacted what.

Thanks for the thoughts, both of you! This is a really interesting discussion and I am totally here for it.

@eyelidlessness I think we have really similar ideas about what a tool for building interactive sites should look like! I'm not necessarily opposed to opening Microsite up to other compilation targets, but it does have the potential to add a lot of complexity. Like Ryan mentioned, every different library comes with its own set of approaches that would need to be smoothed over in some way. I'm honestly not sure where I'd start with that. The added codebase complexity to performance payoff might not be worth it.

I chose Preact primarily for its size but also familiarity for the many React devs out there. I think it fits Microsite's use case really well. I'm still focused on stabilizing Microsite and adding features, so I think this idea will have to go on the back burner for now. I'll be keeping an eye on JSX Lite and considering this target agnostic idea, though.