Comments (26)
there is also one nice, fitzgen/dodrio
from seed.
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.
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.
Once that stabilizes, if it's easy enough to integrate (sounds like that's a goal) I'm open to using it.
from seed.
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.
(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.
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.
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.
dominator is stdweb based
oh, I didn't see that. A
therefore not a potential candidate,
I totally agree!
from seed.
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.
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.
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.
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.
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 supportstdweb
- How to integrate with a specific framework such as
seed
orYew
? For example: integration with theirs message system?
from seed.
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.
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.
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.
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.
Maybe just put it aside as a branch then you may come back and have another look later?
from seed.
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.
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.
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.
from seed.
@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.
Agree - didn't realize before that it requires a different app design/API.
from seed.
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)
- 1. Create a new issue in the Seed repo with the name and copy-paste this checklist into it (also add blockers and additional tasks, if exist).
- Maintenance & Future of Seed HOT 8
- v0.9.1: browser::json::Error is inaccessible
- Deserializing large numbers fail HOT 11
- Websocket example does not work HOT 2
- how to integrate with another wasm ?
- Websocket API changed from 0.8 to 0.9 HOT 5
- DOM node is not attached to ElRef under some conditions HOT 6
- Does not build with wasm-bindgen 0.2.81 HOT 3
- Closures need types HOT 3
- Release v0.9.2 HOT 3
- Seed 0.8 accepting the newest wasm-bindgen HOT 3
- [0.8.x] WebSocket and too early dropped closure HOT 1
- support `beforeinput` events HOT 1
- Seed doesn't compile with `default-features = false` HOT 2
- checkbox not working HOT 2
- Release v0.10.0 HOT 3
- Cannot use subs (subs::UrlChanged) HOT 2
- Error: unresolved import in wasm_bindgen_initialize HOT 1
- Website defaced by indonesian (?) script-kiddie HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from seed.