-
Notifications
You must be signed in to change notification settings - Fork 24
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
Explore addition of a Virtual/Incremental DOM mechanism #13
Comments
Something like this sounds simple enough: /~https://github.com/localvoid/kivi/blob/26eae1043efb9cc4ba7e54c1c4ab30389a669149/lib/vnode.ts#L1284-L1518 |
If I understand correctly, Binding.scala resolves this issue with observable sequence ( |
You'r spot on!
We could, but I would personally like to implement the more general solution of tree diffing. Let me explain what I dislike about a sequence only solution:
|
Thanks, @OlivierBlanvillain! I understand now difficulties with |
Would it make sense at all to make a separate library that does patch directly on |
@bbarker I think that could work, here are a few things to take into consideration:
|
MetaRx solves the problem with delta objects: |
@fdietze This looks like the same solution that what's used in Binding.scala. As explained in this previous comment, I would rather go for a solution that does not require users to write in an imperative style. Let me give an example of why I dislike the delta objects approach. Suppose I want to implement this page: https://en.lichess.org/games. I already have all my business logic implemented in term of the following: case class Chessboard(...) // Something that's easy to display on the screen
case class Move(from: Pos, to: Pos) // Any move on the board
def applyMove(m: Move, c: Chessboard): Chessboard =
??? // All the game logic goes here
def renderBoard(c: Chessboard): scala.xml.Node =
??? // All the front-end work goes here If I want to animate the boards on the With React style dom diffing, I can keep all the existing logic (and the super simple |
Ok, I understand. So maybe a hybrid approach would make sense. Delta updates only for common data-structures (like Lists) and Virtual DOM diffs for custom ones. |
Everything in the library was built to encourage immutability / referential transparency, I don't think exposing a mutable API for a few data-structures would fit well with what's already there... Also, with a diff algorithm in place, why would you ever want to formulate your business logic in term of patches instead of functions over immutable data structures? |
I think the delta-approach doesn't necessarily need to be implemented with mutable data structures. The whole point are efficient updates which is also achievable with immutable datastructures. This should preserve the referential transparency property. Am I overlooking something? I agree that you probably never want to formulate patches in your business logic. That's why some common data structures like lists should do that automatically. The usage would only shift from manipulating the immutable list manually to using methods to manipulate the reactive immutable list (and automatically handling the diff-part). Does that make sense? |
I have the impression that this is not the way it works in other libraries implementing delta objects, for example looking at the js-framework-benchmark for Binding.scala none of this is referentially transparent (they are mutations happening under the hood). But if you have ideas for a different design I'm all yours! |
Binding.scala users usually use normal They usually performs coarse-grained source updating, which triggers fine-grained dom updating. For example: /~https://github.com/walfie/gbf-raidfinder/blob/master/client/src/main/scala/walfie/gbf/raidfinder/client/ViewModel.scala#L72 |
This is exactly what I mean by imperative style. In a way, Binding.scala imposes the use of mutable data structures (to get good performances). In the // Pure function
def applyMove(m: Move, c: Chessboard): Chessboard to // Updates the Var in c: Chessboard
def applyMove(m: Move, c: Chessboard): Unit Diff/patch algorithms solves this, you can use immutable data structures and pure functions while still getting the benefits of minimal DOM updates. |
@OlivierBlanvillain That's why the library name is Binding.scala 😄 |
I think FRP is a good tool for modelling state machine. On the other hand, data-binding is better for UI. |
I would personally pick referential transparently over the alternatives any day of the week, but what's better ultimately comes down to preferences, so let's not get into that 😉. Regarding FRP vs data-binding, I think the two are not mutually exclusive! Indeed, putting When handling users inputs, say button clicks, you essentially have the choice between directly mutating your business logic state on some existing Anyway, that's a really interesting discussion, I should factor some of this out in the FAQ as it nicely summaries the hybrid nature of the design 😄 |
Maybe data-binding can be seen as a special case of FRP. And of course, patching data on |
Any update for this issue? |
With regard to data binding and cached values, this is being handled in
#94. I don't know of any work so far being done on vdom diffing.
…On Sat, Mar 17, 2018 at 1:32 AM, Tao ***@***.***> wrote:
Any update for this issue?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#13 (comment)>,
or mute the thread
</~https://github.com/notifications/unsubscribe-auth/AA37jslY4Q6AkHt9q4oRbgpvWaif5HNeks5tfJ_ogaJpZM4KlMs4>
.
--
Brandon Barker
brandon.barker@gmail.com
|
I found some relevant papers which could help building a good alternative to vdom: raquo/Laminar#14 |
Especially needed to deal with mutable
Seq
s. Here is an abstract for the project:Functional reactive programming (FRP) is a popular paradigm for developing web interfaces, but care needs to be taken in the DOM binding mechanism in order to have good performance.
State of the art DOM binding libraries such as Facebook React relie on (virtual) DOM diffing mechanism to obtain best performances. On every update, a complete view of the application is generated in memory. The framework then compute a diff between current and previous view to finally apply the minimum changes to the DOM.
Another approach, called precise binding, makes use of FRP constructs to build views while maintaining a dependency graph of
Rx
s, values susceptible to changes over time. This mechanism, currently using in themonadic-html
library, allows changes to be propagate very precisely to the DOM. However, depending on the granularity of mutations, idiomaticmonadic-html
can be inefficient when re-rendering large portions of the DOM for small changes.The goal of this project is to design a DOM diffing algorithm in Scala.js which could be combined with the existing precise binding mechanism to obtain an hybrid approach. Depending on time, the project would include benchmarks to compare this hybrid binding approach with existing solutions.
The text was updated successfully, but these errors were encountered: