Code Monkey home page Code Monkey logo

Comments (26)

luover avatar luover commented on September 16, 2024 5

there is also one nice, fitzgen/dodrio

from seed.

rsaccon avatar rsaccon commented on September 16, 2024 3

instead of narrowing down on existing Rust virtual DOM implementations I just did the opposite: I read some articles on fast approaches for DOM updating, might be an inspiration when it comes to optimizing the Seed virtual DOM implementation.

This is a technique called DOM memoization:

I think similar concepts are also used by hyperHTML and litHTML, which position themselves as lightweight React alternatives.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024 3

Going to start decoupling vdom from the rest of the code. First step is defining a trait that vdom elements will implement. The vdom will use structs implementing this trait, vice the hardcoded dom_types::El. Once complete, I expect another vdom setup to use this trait could be swapped in, or Seed's vdom could be used for another framework implementing this trait.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024 3

Once that stabilizes, if it's easy enough to integrate (sounds like that's a goal) I'm open to using it.

from seed.

rsaccon avatar rsaccon commented on September 16, 2024 2

My two cents: dominator is stdweb based, therefore not a potential candidate, if using an existing crate will be considered seriously. But I just sneaked around in its sources and I found something which might inspire or help when the time comes, to add animations to seed. Dominator provides a requestAnimationFrame based runloop for animations. However not a physical engine for spring-like stuff. And because I couldn't get the examples running, and there is no documentation, I didn't dig any deeper (yet).

from seed.

limira avatar limira commented on September 16, 2024 2

(Eg avoiding recreating the whole seed::dom_types::El structure every state change)

From my first comment in this discussion above:

Simi try to bypass the creation of new virtual DOM in the re-render process

In other words: Simi already took that path, and you (Seed) seem want to go that direction as well.
Interesting enough, Imba (from reading articles provide by @rsaccon above) also have a very similar approach. From its minimum example (I copy it here and add some notes):

tag AppView
    def render
        <self>
            <h1.title> "Welcome"
            <p.desc .red=(Math.random > 0.5)> "Roulette"
                    ^^^^^^^^^^^^^^^^^^^^^^^^ the only expression that may change

It will generate the following code:

class AppView extends Imba.Tag {
  render() {
    var $ = this.$; // inline cache for tag
    return this.setChildren($.$ = $.$ || 
    // Part 1. Initializing Code
    // This portion create elements and init static attributes and content.
    [
      Imba.tag('h1',$).flag('title').setText("Welcome"),
      Imba.tag('p',$).flag('desc').setText("Roulette")
    ]).synced(
    // Part 2. Updating Code
    // This portion update non static values.
      $[1].flagIf('red',Math.random() > 0.5)
    );
  }
}

If I understand correctly, If it is the first render: both Part 1 and Part 2 will be executed. If the elements already exists, then, only Part 2 of the code executes.

In conclusion, the underlying magic of Imba is the way it generates codes to separate static and non static content (and only execute relevant code). It is also how Simi works with the help of procedural macro.

but perhaps it would no longer hold things like text, attributes, children etc.

I am not sure if there is a way to avoid storing these things. I still need to store them (the non static ones) in the virtual DOM.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024 1

Agree. From a skim, it looks like these are not especially modular, or at least not documented as such. Ie, could be done, but not without a lot of work. I like the idea of modular bindgen-based parts like this, but not sure how to approach integrating. Short of full-integration, implementing good ideas like requestAnimationFrame would be a start.

It would be nice to have a standalone, well-documented virtual DOM crate that any bindgen framework could use.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024 1

The latest commit shows my current attempt at decoupling the vdom from the dom_types module, using a trait. It's currently in a broken state due to sizing problems.

from seed.

flosse avatar flosse commented on September 16, 2024

dominator is stdweb based

oh, I didn't see that. A

therefore not a potential candidate,

I totally agree!

from seed.

limira avatar limira commented on September 16, 2024

Hi, I am the author of Simi. Simi try to bypass the creation of new virtual DOM in the re-render process. Therefore, its virtual DOM is very special, I think it is not very useful for other frameworks.

You may interest in typed-html instead?

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

It looks like typed-html has a similar issue to what you describe with Simi: It appears tightly-coupled with its html macro.

from seed.

limira avatar limira commented on September 16, 2024

Because Simi is going in a very different direction, I just have a quick look at type-html, hence may be my thought is wrong. But I think type-html's macro is just a helper to translate JSX-like syntax into its equivalent Rust code to build its DOMTree. If typed-html's DOMTree is suitable for your use case, you are absolutely able to create your own macro to implement a different syntax.

from seed.

rsaccon avatar rsaccon commented on September 16, 2024

I think type-html is also not relevant here, because, as its name says, it is about typed HTML or plain HTML as syntax, like JSX. But seed uses a different approach to represent HTML, programmatically.

from seed.

limira avatar limira commented on September 16, 2024

I am not sure it is relevant or not. If the answer is "no", then, the reason is not what you think: plain HTML as syntax, like JSX. Because you can ignore its default macro, and implement your own macro that supports a different syntax (similar to the way I try to implement an alternative macro - which is discontinued and never release - for Yew).

From what I understand, typed-html try to ensure correct use of html tags, attributes at compile time. You can look at
element.rs and see that it define traits such as: FlowContent, TableContent... That is the way to help validating correctness at compile time. The author say it explicitly in the README:

any element which accepts children will have a restriction on the type of the children

At the end of the README:

Render to a virtual DOM

... You can walk this virtual DOM tree and use it to build an actual DOM tree with stdweb or pass it on to your favourite virtual DOM system.

It's clear that one of the intention of the author is for use in a specific framework.

Problems that I can see:

  • typed-html is still only support stdweb
  • How to integrate with a specific framework such as seed or Yew? For example: integration with theirs message system?

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

I like the idea of moving to something more efficient than the current React-style vDOM (Eg avoiding recreating the whole seed::dom_types::El structure every state change). Need to evaluate existing approaches (Or come up with a new variant), and make major changes internally... but shouldn't affect API.

It seems like we'd still need the El struct to wrap web_sys Elements, but perhaps it would no longer hold things like text, attributes, children etc.

from seed.

rsaccon avatar rsaccon commented on September 16, 2024

I took a closer look at Simi. @limira, I am very impressed with your work. Probably the most optimized virtual node implementation in Rust ! Also the docs and the provided tooling makes it super easy to try it out. And it is great to have its author participating in this thread here. However the performance gain (I assume) comes at at cost of much higher complexity, a very different concept than just virtual-node-diffing and the requirement of nightly rust. Well, it is up to @David-OConnor to decide and prioritize, when and how to do virtual node optimization and what role will play Simi or any other existing implementation.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

Top priority is getting http requests (ie fetch) working in a high-level API. (eg: data = seed::get('https://test.com', headers), or something async with a callback) No luck so far due to problems with futures. Once complete, this would be more suitable as a standalone crate any bindgen-using framework could use. (Reqwest/hyper etc don't work on the wasm32-unknown-unknown target.)

In Seed's current approach, we lose information that could be used to determine which elements to diff/re-render during the vdom-recreation step. (eg calling the update func on the view func); this new vdom tree doesn't know which info came from a change in the model, and which is static... And I don't see any way to directly diff the model. @limira said he worked around this using proc_macros.

From an information-theory standpoint, the pure vdom approach, while simple/elegant to code, is inefficient, and Simi has done a better job of choosing the minimal amount of computation/rendering to accomplish.

Of note: We could get big performance gains with minimal change to the existing vdom by adding an optional static flag that could passed to element macros, but this is ugly.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

To be blunt, this isn't going well. Almost ready to revert to the last release's commit, and abort on this. Loads of errors I'm not sure how to deal with. Would rather put this effort into improving features, docs, etc.

from seed.

limira avatar limira commented on September 16, 2024

Maybe just put it aside as a branch then you may come back and have another look later?

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

Good call. Reverted code to a previous commit. Repo is back in working order. This is trickier than I'd guessed; shelving it for now. The attempt is preserved in the commits done over the past week.

from seed.

sapir avatar sapir commented on September 16, 2024

I tried out seed and ran into serious performance issues. I basically have 2 components: A query box and then a list of query results. If I have enough query results, each keystroke event for the query box triggers enough logic for a delay of over a second.

So I'd like to help fix this, but I don't know what you had in mind for the VDOM implementation.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

The current vdom implementation is simple and easy to reason about, but inefficient. I don't have a strong opinion about the best ways to improve it: Any way to improve efficiency, whether in diffing logic, matching children (eg optional keyed children, something I started work on this morning), an Ember-like vdom alternative, input-field-specific workarounds, grouping re-renders into discrete framerate-based chunks etc.

I suspect the original idea of this issue, creating (or using) a plug+play vdom, is intractable, but there's lots of room for efficiency improvement.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

rustwasm/gloo#11

from seed.

Pauan avatar Pauan commented on September 16, 2024

@rsaccon My two cents: dominator is stdweb based, therefore not a potential candidate

I just found this thread. I just wanted to mention that I plan to move dominator to wasm-bindgen.

However, even after that, I don't think dominator is appropriate for seed, because it uses a completely different design choice (Signals without any DOM diffing).

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

Agree - didn't realize before that it requires a different app design/API.

from seed.

David-OConnor avatar David-OConnor commented on September 16, 2024

Closing this - There don't appear to be any suitable fits for this, now, or on the horizon. If someone identifies one, open a new issue.

from seed.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.