Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xilem_core roadmap #65

Open
raphlinus opened this issue May 23, 2023 · 0 comments
Open

xilem_core roadmap #65

raphlinus opened this issue May 23, 2023 · 0 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@raphlinus
Copy link
Contributor

As of #61, xilem_core is a separate crate that is generic with respect to the type of the element tree. There are also experiments using this core to generate DOM nodes. Potentially, xilem_core is useful as a standalone reactivity layer, comparable in scope to Dioxus or Leptos.

This issue tracks future development of xilem_core, both for potential web applications and as the reactive layer in a native UI stack. Building out the widget tree and other infrastructure is out of scope of this issue. The hope is that the work can happen in parallel.

A hypothesis to test is whether the Xilem reactive layer is a good alternative to React-like (Dioxus) and fine-grained reactivity (Leptos, Sycamore, Silkenweb). This can be evaluated in a web context, and doing so controls for a number of variables, though doing so misses one potential advantage of Xilem: web more or less forces a single-threaded approach.

The main work on xilem_core is in the following categories:

  • Add more features to xilem_core
  • Develop xilemsvg and possibly create a xilemweb
  • Explore scripting integration
  • Validate the design
  • Document and explain

We'll expand on each of those in their own sections

Add more features to xilem_core

The current state of the code is very minimal; there are features that have been prototyped in other repos and not adapted to the current architecture, and also features for which there is design work but not yet an implementation.

Three important "architectural" View implementations are adapt, memoize, and use_state. Prototypes exist in the xilem_tokio branch. It should be relatively straightforward to adapt these.

One question on memoize is whether we try to model the concept of "same" (which is captured in the Data trait from Druid), or the sloppier but more ergonomic choice of using PartialEq. It's worth noting that while the signature memoize in the xilem_tokio prototype has a Clone bound, it seems possible to remove.

Of course, one approach is to offer both PartialEq and same variants. For a number of types (strings, etc) there is no significant difference.

Async integration

The xliem_tokio prototype also has async integration. It's not obvious how much of that belongs in xilem_core and how much should be implemented in clients. A good criterion for decision is how much this logic can be made actually generic. Since these views spawn work, there is a dependency on a runtime; on wasm, this can simply be a call to wasm_bindgen_futures::spawn_local.

See draft blog post on Xilem async for more discussion of async. Note nontrivial logic for choreographing the rendering. That feels out of scope for xilem_core (especially as not needed in web use cases), but it is open question. Perhaps the actual scheduling logic is out of scope for xilem_core, but support for common patterns would make sense.

Environment

One feature common to most reactive frameworks is the concept of an environment (also commonly called "context") where a parent view can set some data, and child views can query it. This is a form of dynamic scoping, and can also be seen as a flow of data downward in the tree.

It seems practical to implement in Xilem, and likely desirable. There is an extensive Zulip thread with notes on the design.

impl View for Arc<V: View>

In the Elm tradition, memoization is the primary mechanism for skipping re-rendering when there is no corresponding change to the app state. The memoize View supports that pattern (with an extremely similar signature as Elm), but using a closure to defer rendering has ergonomic downsides; in the general case, users will need to wrap a relevant chunk of app state in an Arc and move a clone of that into the closure. An alternative is for the app to maintain pre-rendered views and paste them into the view tree (also by cloning an Arc).

There is a Zulip thread with fairly detailed notes on implementing this feature, as well as considering its implications. Naming the type of the retained View is challenging, so either type alias impl trait (not yet in stable Rust) or type erasure would be useful.

Diffable sparse data structures

The plan for (potentially) large collections in Xilem is the use of diffable sparse data structures. It's not obvious whether these belong in xilem_core or in separate crates; the underlying data structures almost certainly do, but there may be useful glue specific to Xilem as well. Note that imbl already handles sparse diffing well in its OrdMap type, but not in the corresponding sequence type.

Ideas for sparsely diffable sequences are described in a RustLab 2020 talk, and there is some prototype code implemented in xi-rope, but this hasn't been landed. It may make sense to start with a placeholder (implemented on Vec) with the correct semantics and API but O(n) performance, to be replaced by a rope-like data structure later.

Template diffing

One possible feature I'll list is template diffing, which has successfully been used for significant performance improvements in Dioxus. However, I'm not yet convinced it's worth the complexity; it seems to me to force the use of compile time macros to analyze which parts of the template are static and which dynamic, while the current Xilem design is not dependent on macros. Even so, I think it can be done within the Xilem framework and may be worth exploring, even if only to gather quantitative performance data.

Explore scripting integration

One motivation for Xilem is to enable bindings with scripting languages; this was a limitation of Druid and is nontrivial in general. Among other things, such language bindings generally require type erasure (AnyView), as modeling the View tree in static types won't work.

There was a Python prototype built, on a very old version of Xilem (back when it was still called "idiopath") that demonstrated a simple button and container example.

Given the potential of such languge bindings, it seems worth continuing to explore, and also discovering what works well and what is more of a pain point.

I should note here that the need to support dynamically typed scripting puts some constraints on the View schema. As one example, custom alignments in SwiftUI are implemented by creating custom (generally zero-size) types that conform to the AlignmentID protocol (and implement a defaultValue static method). It might be possible to adapt that to a Python, but it seems challenging.

Develop xilemsvg and possibly xilemweb

There is an experiment of creating SVG dom nodes from Xilem Views. One reason for this particular focus is to explore also implemeting native rendering from the same View tree.

I've also done a small amount of prototyping of using a generic Xilem View to create HTML DOM nodes (not published, and based on a version that predates the current xilem_core). This experiment could be significantly expanded. A good early milestone is re-creating TodoMVC.

Making a real reactive layer is a large task; there's a significant amount of work specific to running in a web browser context.

One potential exploration with xilemweb is to integrate with Blitz.

Validate the design

I obviously feel that xilem_core has the potential to be a great reactive layer for UI in Rust. However, there is currently very little evidence to support such a claim. A great deal of the validation can be done in a Web context. The main criteria are:

  • Conciseness
  • Performance
  • Expressiveness
  • Flexibility
  • Overall developer ergonomics

One way to evaluate performance is to participate in the js-framework-benchmark (see Sledgehammer for more details on running this in a Rust WASM context). However, there are some caveats. Because it of its web-centric nature, it cannot capture the ability to exploit parallelism through multithreading.

The "flexibility" line captures the suitability across a range of use cases. One open question is whether xilem_core is usable as-is without an explicit state management layer, or whether it makes sense to add one. One exploration is integration with hornpipe.

Similarly, we'll want to evaluate whether the adapt View actually facilitates factoring a larger application into components. It's always tricky to model interactions between components.

Document and explain

A codebase, even of crystalline perfection, is of little use unless people can actually understand how to use it. There are a few breadcrumbs of documentation, but to be viable, xilem_core needs a good writeup.

Starting points:

@raphlinus raphlinus added enhancement New feature or request help wanted Extra attention is needed labels May 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant